1.面向对象编程5. 面向对象编程
用解决现实中的问题的办法来解决计算机问题。
5.1 对象
Anything is Object. 万物皆对象。
现实中对象是一种客观的存在,程序中对象是一片内存空间。
对象之间各司其职,各尽所能,对象功能单一。对象之间通过发消息来互相合作,形成一个系统。
对象
有什么      属性
能干什么   方法
5.2 类
就是类型,这儿理解为用户自定义的类型。
          int double float ... 基本数据类型
          TRDate ...               用户自定义类型
类是一种主观的认识,是对我们需要解决的问题的一种抽象,是创建对象的模型。 
5.3 定义类
    @interface 类名 : NSObject
         属性的定义
         方法的声明
    @end
    让类继承NSObject是因为需要类拥有相应的能力,比如内存分配能力等。
    @implementation 类名
         方法的定义
    @end
5.4 创建对象
    类名* obj = [类名 alloc];
    [obj 消息]; //给对象发消息
    对象收到消息会调用方法。方法其实是一种特殊的函数。6. 内存分配
    OC中的对象全部放在堆中。 要使用堆中的对象,必须使用指针指向对象。经常把这个指针叫"引用"。要让对象工作,就给对象发消息,如果对象响应消息,就会调用对应的方法。消息是通过引用发的。
    堆内存,分配和释放不是自动的,而是由程序控制的。
    堆里放的是对象,栈里放的是引用,引用指向了对象。7. 实际开发中类定义的文件分离
              一个类,一般会分成两个文件,一个.h,一个.m。
              .h文件中定义类的interface部分,.m文件中定义类的implementation部分。类名和文件名应该保持一致。
//以下代码在XCode下编写main.m#import <Foundation/Foundation.h>
@interface MyFirstClass : NSObject   //继承NSObject,是所有类的老祖宗,分配内存空间
@Property int prop1;    //属性的定义
- (void) method1;      //方法的声明
@end//实现部分
@implementation MyFirstClass
- (void) method1
{
NSLog(@"我是一个方法");
}
@end
@interface TRDog : NSObject  //狗类
@property NSString *name;    //OC语言特有的类型,用户自定义类型需指针
- (void)bark;
@end@impementation TRDog
-(void)bark
{
NSLog(@"%@在旺旺的叫", self.name);   //%@打印字符串
}
@endTRDog* getDog()
{
        TRDog *dog = [TRDog alloc];
        dog.name = @"小Mu";
        return dog;  //对象在堆中,可以返回
}int main(int argc, const char* argv[])
{
@autoreleasepool{
MyFirstClass *obj = [MyFirstClass alloc];   //对象的创建
[obj method1];   //调用方法
TRDog *dog = [TRDog alloc];
dog.name = @"旺财";
[dog bark];
TRDog *dog2 = getDog();
[dog2 bark];
//[obj release];  //编译器会自动写上
//[dog release];
//[dog2 release];
}
return 0;
}
//重新新建一个文件TREmployee.h,定义一个employee类
#import <Foundation/Foundation.h>
//类的接口部分
@interface TREmployee : NSObject
//定义属性
@property NSString *name;
@property int age;
@property BOOL gender;
@property double salary;
//声明部分
- (void) show;
@end//新建一个文件TREmployee.m,写implementation部分
#import "TREmployee.h"    //需import
@implementation TREmployee
- (void) show
{
        NSLog(@"%@,%@,%d,%.2lf", self.name, self.gender?@"男":"女", self.age, self.salary);
}
@end//main.m中:
#import "TREmployee.h"
void test2()
{
        TREmployee *e = [TREmployee alloc];
        e.name = @"Daniel";
        e.age = 30;
        e.gender = YES;
        e.salary = 123456.78;
        [e show];
        //[e release];        
}int main(int argc, const char* argv[])
{
@autoreleasepool{
test2();
}
return 0;
}

解决方案 »

  1.   

    1. 方法(method)
        就是类中的函数,写法和函数不同
        -(返回值类型)方法名;    //无参数
        -(返回值类型)方法名:(参数类型)参数名;    //一个参数
        -(返回值类型)方法名:(参数类型)参数1 :(参数类型)参数2 ...;    //多个参数
        -(返回值类型)部分方法名:(参数类型)参数1 部分方法名:(参数类型)参数2 ...    ":"是方法名的一部分。//在TREmployee.h中:
    #import <Foundation/Foundation.h>@interface TREmployee : NSObject
    @property NSString *name;
    @property int age;
    @property BOOL gender;
    @property double salary;
    - (void) show;    //无参方法
    - (void)raiseSalary: (double) money;   //一个参数
    - (double) getSlary;
    - (NSString*)genderToString;    //返回的是一个对象需用*,返回地址,引用(指针)
    - (void) changeName: (NSString*) newName;    //OC对象传递需用指针,对象不能随便拷贝
    - (void)set: (NSString*) newName :(int)newAge;    //两个参数
    - (void)set: (NSString*) newName :(int)newAge :(BOOL)newGender : (double)newSalary ;    //四个参数
    //方法名由若干部分组成
    - (void)setName: (NSString*)newName andAge: (int)newAge;    //部分方法名
    - (void)setName: (NSString*)newName 
                        age: (int)newAge
                    gender:(BOOL)newGender
                       salary:(double)newSalary;
    @end//在TREmployee.m中:
    #import "TREmployee.h"
    @implementation TREmployee
    - (void) show    //无参方法
    {
            NSLog(@"%@, %@, %d, %g", self.name, [self genderToString], self.age, self.salary);
    }
    - (void)raiseSalary: (double) money   //一个参数
    {
            self.salary += money;
    }
    - (double) getSlary
    {
            return self.salary += money;
    }
    - (NSString*)genderToString    //返回的是一个对象需用*,返回地址,引用(指针)
    {
            return self.gender?@"男":@"女";
    }
    - (void) changeName: (NSString*) newName    //OC对象传递需用指针,对象不能随便拷贝
    {
            self.name = newName;        
    }
    - (void)set: (NSString*) newName :(int)newAge    //两个参数
    {
            self.name  = newName;
            self.Age = newAge;
    }
    - (void)set: (NSString*) newName :(int)newAge :(BOOL)newGender : (double)newSalary 
    {
            self.Name = newName;
            self.Age = newAge;
            self.Gender = newGender;
            self.salary = newSalary;
    }
    - (void)setName: (NSString*)newName andAge: (int)newAge   //部分方法名
    {
            self.name = newName;
            self.Age = newAge;
    }
    - (void)setName: (NSString*)newName 
                        age: (int)newAge
                    gender:(BOOL)newGender
                       salary:(double)newSalary
    {
            self.name = newName;
            self.age = newAge;
            self.gender = newGender;
            self.salary = newSalary
    }
    @end//在main.m中:
    #import "TREmployee.h"void test1()
    {
            TREmployee *e = [TREmployee alloc];
            [e show];
            e.name = @"Daniel";
            [e set:@"Daniel" :30];
            [e show];
            [e raiseSalary:10000];
            [e show];
            [e set: @"Daniel" :30 :YES :1234567.78];
            [e show];
            [e changeName: @"Guodh"];
            [e show];
            [e set:@"Guodenghong" :31 :YES :123456.78];
            [e setName:@"Daniel" andAge: 32];
            NSLog(@"你的工资是多少:%g", [e getSalary]);
            [e setName:@"Daniel" age:30 gender:YES salary:12345];    //部分方法名,最实用
    }int main(int argc, const char *argv[])
    {
            @autoreleasepool {
                    test1();
            }
            return 0;
    }
      

  2.   

    3.实例方法和实例变量
    2. 实例变量(InstanceVariable)    
        (一个对象会有自己独特的数据和别的对象不同,这些数据会保存在一些特殊的变量值中,这种变量叫实例变量。类的每个实例(对象)都有一份。)
        用一个类,创建出了一个对象,那我们说这个对象就是此类的一个实例。一个类可以有很多的实例。每一个实例都拥有一份和其他实例不同的数据,这些数据保存在实例变量中。
        实例变量可以定义在interface部分,也可以定义在implementation部分。3. 属性//
    //  Student.h
    //  day02-2
    //
    //#import <Foundation/Foundation.h>@interface Student : NSObject
    {
        //实例变量 保存值的
        int _age;
        char _sex;
        float _salary;
    }
    //給实例变量赋值
    //setter 属性名:int age
    -(void)setAge:(int)age; //此age为参数
    -(int)age;
    -(void)setSex:(char)sex;
    -(char)sex;
    -(void)setSalary:(float)salary;
    -(float)salary;
    @end
    //
    //  Student.m
    //  day02-2
    //
    //#import "Student.h"@implementation Student{
        int _level; //声明了一个私有的实例变量(放在.m中的实例变量是私有的)
    }
    -(void)getLevel{  //声明了一个私有的实例方法(放在.m中的实例变量是私有的)
        NSLog(@"getLevel");
    }-(void)setAge:(int)age{
        _age = age;  //属性和实例变量的关系
        NSLog(@"调用了setter方法");
    }-(int)age{
        return _age;
    }-(void)setSex:(char)sex{
        _sex = sex;
    }-(char)sex{
        return _sex;
    }-(void)setSalary:(float)salary{
        _salary = salary;
    }-(float)salary{
        return _salary;
    }@end
    //
    //  main.m
    //  day02-2
    //
    //#import <Foundation/Foundation.h>
    #import "Student.h"int main(int argc, const char * argv[])
    {    @autoreleasepool {
            
            Student* stu = [Student alloc];
            //[stu setAge:20];
            //NSLog(@"age:%d", [stu getAge]);
            //[stu setSex:'M'];
            //NSLog(@"sex:%c", [stu getSex]);
            //[stu setSalary:6000.1];
            //NSLog(@"salary:%.2f", [stu getSalary]);
            
            stu.age = 18; //自动调用setter方法
            NSLog(@"age:%d", stu.age); //自动调用getter方法
            
            stu.sex = 'M'; //自动调用setter方法
            int sex = stu.sex; //自动调用getter方法
            NSLog(@"sex:%c", sex);
            
            stu.salary = 12000.5; //自动调用setter方法
            NSLog(@"salary:%.2f", stu.salary); //自动调用getter方法
            
        }
        return 0;
    }
      

  3.   

    3. 属性(Property)
        OC中,属性指提供了getter和(或)setter方法的数据。
        @property int numerator;    //setNumerator numerator
        @property int denominator;    //setDenominator denominator
        本质上,属性是方法(不是变量),属性的值是由实例变量来保存。    3.1 属性的本质
            属性一般由三个部分组成:
                1)保存属性值的实例变量
                        {
                                实例变量类型 实例变量名
                        }
                2)getter和setter方法的声明
                        getter方法的方法名和属性名一样,没有参数,返回值类型和属性类型一样。
                            -(属性的类型)属性名;
                        setter方法的方法名是"set" +属性名并首字母大写+":"+和属性类型一样的参数。
                3)getter和setter方法的实现
                        setter方法的实现主要是用来给属性赋值的。
                        getter方法的实现主要是用来读取属性的值。
                引用.属性 = 值;    ==>会自动调用setter方法
                变量 = 引用.属性;    ==>会自动调用getter方法
        3.2 声明式的属性
            1)定义实例变量
            2)在interface部分声明属性:
                    @property 属性类型 属性名;
            3)在implementation部分生成具体的方法:
                    @synthesize 属性名 = 实例变量名;
                    会自动生成对应的setter和getter方法。
        3.3 从iOS5开始,声明式的属性简化如下:
                可以不定义实例变量,编译器会生成"_属性名"的实例变量,但在implementation部分,还必须生成具体的方法:
                @synthesize 属性名 = _属性名;
        3.4 从iOS6开始,声明式属性又简化:
                只需要用@property声明属性即可,实例变量和getter,setter方法的具体实现会自动生成,不需要程序员干涉。
                如果你不满意编译器生成的部分,可以自己写。
    //
    //  Point2_1.h
    //  day02-4
    //  属性的第1个版本
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import <Foundation/Foundation.h>@interface Point2_1 : NSObject
    {
        int x;
        int y;
    }
    -(void)setX:(int)newX;
    -(int)getX;
    -(void)setY:(int)newY;
    -(int)getY;@end//
    //  Point2_1.m
    //  day02-4
    //
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import "Point2_1.h"@implementation Point2_1-(void)setX:(int)newX{
        x = newX;
    }-(int)getX{
        return x;
    }-(void)setY:(int)newY{
        y = newY;
    }-(int)getY{
        return y;
    }@end
    //
    //  Point2_2.h
    //  day02-4
    //  属性的第2个版本
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import <Foundation/Foundation.h>@interface Point2_2 : NSObject
    {
        int _x;
        int _y;
    }
    -(void)setX:(int)x;
    -(int)getX;
    -(void)setY:(int)y;
    -(int)getY;
    @end
    //
    //  Point2_2.m
    //  day02-4
    //
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import "Point2_2.h"@implementation Point2_2-(void)setX:(int)x{
        _x = x;
    }-(int)getX{
        return _x;
    }-(void)setY:(int)y{
        _y = y;
    }-(int)getY{
        return _y;
    }@end
    //
    //  Point2_3.h
    //  day02-4
    //  属性的第3个版本
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import <Foundation/Foundation.h>@interface Point2_3 : NSObject
    @property int x;
    @property int y;
    @end
    //
    //  Point2_3.m
    //  day02-4
    //
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import "Point2_3.h"@implementation Point2_3
    @synthesize x = _x;
    @synthesize y = _y;
    @end
    //
    //  Point2_4.h
    //  day02-4
    //  属性的第4个版本
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import <Foundation/Foundation.h>@interface Point2_4 : NSObject
    @property int x;
    @property int y;
    @end
    //
    //  Point2_4.m
    //  day02-4
    //
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import "Point2_4.h"@implementation Point2_4@end//
    //  main.m
    //  day02-4
    //
    //  Created by tarena on 14-3-18.
    //  Copyright (c) 2014年 tarena. All rights reserved.
    //#import <Foundation/Foundation.h>
    #import "Point2_1.h"
    #import "Point2_2.h"
    #import "Point2_3.h"
    #import "Point2_4.h"int main(int argc, const char * argv[])
    {    @autoreleasepool {
            
            Point2_1* p1 = [Point2_1 alloc];
            [p1 setX:10];
            [p1 setY:20];
            NSLog(@"p1:(%d,%d)", [p1 getX], [p1 getY]);
            
            Point2_2* p2 = [Point2_2 alloc];
            [p2 setX:11];
            [p2 setY:21];
            NSLog(@"p2:(%d,%d)", [p2 getX], [p2 getY]);
            
            Point2_3* p3 = [Point2_3 alloc];
            p3.x = 31;
            p3.y = 23;
            NSLog(@"p3:(%d,%d)", p3.x, p3.y);
            
            Point2_4* p4 = [Point2_4 alloc];
            p4.x = 41;
            p4.y = 14;
            NSLog(@"p4:(%d,%d)", p4.x, p4.y);
            
        }
        return 0;
    }