1.1 OC class new summary
1.http://www.cnblogs.com/mjios/archive/2013/04/06/3002814.html
2.How to create a oc class?
3.
3.1 In which two files? What did they create for?
3.2 How to judge a function is static or dynamic?
3.3成员变量的常用作用域有3种?
3.4 How to write in .h file?(no member)
3.5 How to write in .m file?(no member)
3.6With one member variable.(.h statement)
3.7With one member variable.(.m realization)
3.8 Create object.(In main)
4
4.1方法的_和_,都必须以 _或者_开头
4.2在.h中声明的所有方法作用域都是_类型,不能更改
4.3 analysis
1 #import <Foundation/Foundation.h> 2 3 @interface Student : NSObject 4 5 @end
1> 看第3行,OC中使用关键字_来声明一个类,_后面紧跟着_Student。
2> 类名Student后面的冒号"_"表示继承,即第3行代码的意思是_。
3> 因为NSObject被声明在_中,所以在第1行用_包含了_文件。
4> 第5行的_表示类的声明结束了。_和_是配套使用的。
4.4
1 #import "Student.h" 2 3 @implementation Student 4 5 @end
1> 看第3行,OC中使用关键字_来实现一个类。_后面紧跟的类名,表示究竟要实现哪一个类。
2> 因为Student这个类是声明在Student.h中的,所以在第1行用#import包含了_文件
3> 第5行的_表示类的实现结束了。_和@_是配套使用的。
4.5
前面我们定义了一个成员变量age,它的作用域是@protected,外界不能直接访问它。为了保证面向对象数据的封装性,我们可以提供age的_方法和_方法,让外界间接访问age。接下来在Student中添加age的get方法和set方法。
1.在Student.h中声明方法
#import <Foundation/Foundation.h> @interface Student : NSObject { int age; // 年龄 @public int no; // 学号 int score; // 成绩 @protected float height; // 身高 @private float weight; // 体重 } // age的get方法 - (int)age; // age的set方法 - (void)setAge:(int)newAge; @end
1> 第18行声明了age的_方法,方法名就叫做age,OC建议_方法的名字跟成员变量保持一致(如果是在Java中,就应该叫做getAge)
2> 第18行最面的 - 表示这是一个_( + 则表示_)。age前面的_表示方法的返回值为int类型,方法的返回值和参数类型都需要用小括号()包住
3> 第21行声明了age的set方法,前面的 - 表示动态方法,(void)表示方法没有返回值
4> 在OC方法中,一个冒号:对应一个参数。由于第21行age的set方法接收一个int类型的参数,参数名为newAge,所以(int)newAge前面有一个冒号:
5> 一定要记住:一个冒号:对应一个参数,而且冒号:也是方法名的一部分。因此第21行set方法的方法名是_,而不是setAge
再加大一下难度,假如增加一个方法可以同时设置age和height,那么就应该这样写:
1 - (void)setAge:(int)newAge andHeight:(float)newHeight;
* 这个方法是动态方法、没有返回值,接收2个参数,所以有2个冒号:
* 这个方法的方法名是_:
* 其实andHeight是可以省略的,它只是为了让方法名念起来通顺一点,也让(float)newHeight前面的冒号:不那么孤单
4.6
前面已经定义了一个Student类,成员变量和方法都有了,接下来看一下怎么使用这个类创建对象。
2> 在OC中创建对象也需要按顺序做上面所述的2件事
1)调用Student类的静态方法_分配存储空间
Student *stu = [Student alloc];
- OC是方法调用是用中括号[ ],方法调用者写在括号左侧,方法名写在括号右侧,中间留点空格。因此上面是调用了Student类的静态方法_。
- 上面调用的alloc方法会返回分配好内存的Student对象,在等号左边用了一个指向Student类型的指针变量stu来接收这个对象,注意stu左边的*号。所有OC对象都是用指针变量来接收的,如果你不了解指针,你记住下面这点就行了:利用类名定义一个变量时,类名后面一定要带个*号。
2)调用Student对象的构造方法_进行初始化
前面调用alloc方法返回的Student对象stu是不能正常使用的,因为仅仅是分配了内存,并没有进行初始化,接下来调用对象的_方法进行初始化
stu = [stu init];
看清楚了,由于init是动态方法,所以这里使用stu变量来调用,并不是使用类名来调用。init会返回已经初始化完毕的对象,再次赋值给了stu变量。这时候的Student对象stu才能正常使用。
3)其实,我们最常见的做法是将_和_连起来使用:
Student *stu = [[Student alloc] init];
相信有面向对象开发经验的你一眼就能看懂了,在main.m完整代码的第7行。
3.销毁对象
由于OC不支持垃圾回收,因此当不再使用某个对象时,需要调用对象的_方法释放此对象。我们在第9行销毁了stu对象。
[stu release];
这个release方法在这里调用一次即可,不要觉得多调用多几次,对象就会释放地干净一点,这样做会很危险,容易造成野指针错误。
4.其他
1> 也可以调用静态方法_快速创建一个对象
1 Student *stu = [Student new]; 2 3 [stu release];
不过我们还是习惯使用alloc和init来创建对象
2> 前面我们调用了Student的alloc、init、new方法,但是你会发现Student.h中并没有声明这些方法,为什么能够调用呢?原因很简单,这些方法都是父类NSObject的,子类当然可以调用父类的方法。
4.7
前面已经成功创建了一个Student对象,接下来访问一下它的公共变量和方法。
1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 @autoreleasepool { 7 Student *stu = [[Student alloc] init]; 8 9 // 访问公共变量no 10 stu->no = 10; 11 12 // 调用setAge:方法设置变量age的值 13 [stu setAge:27]; 14 15 // 调用setAge:andHeight:方法同时设置变量age和height的值 16 [stu setAge:28 andHeight:1.88f]; 17 18 // 访问公共变量no 19 int no = stu->no; 20 // 调用age方法获取变量age的值 21 int age = [stu age]; 22 23 // 打印no和age的值 24 NSLog(@"no is %i and age is %i", no, age); 25 26 [stu release]; 27 } 28 return 0; 29 }
1.第7行创建了Student对象,第26行销毁了对象
2.第10行和第19行访问了Student对象的公共成员变量no,如果不是公共变量,不能像这样直接访问。注意访问方式:对象->成员变量
3.第13行调用了Student对象的setAge:方法,传入参数27修改了成员变量age的值
4.第16行调用了Student对象的setAge:andHeight:方法,同时修改了成员变量age和height的值
5.第21行调用了Student对象的age方法获取成员变量age的值
6.第24行输出了age和no的值,输出结果:
2013-04-06 21:54:56.221 第一个OC程序[1276:303] no is 10 and age is 28
------------------
Answer
2. 2.1 XCode new file-> OS X .cocoa oc-class->name+NSObject
2.2 .h statement
2.3 .m realization
2.4 main() create object
3.1 .h .m
3.2 +static(class) -dynamic(object)
3.3 @public @private @protected
3.4
#import <Foundation/Foundation.h>
@interface Student : NSObject
@end
3.5
#import "Student.h" @implementation Student @end
3.6
#import <Foundation/Foundation.h> @interface Student : NSObject { int age; // 年龄 } @end
#import <Foundation/Foundation.h> @interface Student : NSObject { int age; // 年龄 @public int no; // 学号 int score; // 成绩 @protected float height; // 身高 @private float weight; // 体重 } // age的get方法 - (int)age; // age的set方法 - (void)setAge:(int)newAge; @end
- (void)setAge:(int)newAge andHeight:(float)newHeight;
3.7
#import "Student.h" @implementation Student // age的get方法 - (int)age { // 直接返回成员变量age return age; } // age的set方法 - (void)setAge:(int)newAge { // 将参数newAge赋值给成员变量age age = newAge; } // 同时设置age和height - (void)setAge:(int)newAge andHeight:(float)newHeight { age = newAge; height = newHeight; } @end
3.8
#import <Foundation/Foundation.h> #import "Student.h" int main(int argc, const char * argv[]) { @autoreleasepool { Student *stu = [[Student alloc] init]; [stu release]; } return 0; }
4
4
4.1方法的声明和实现,都必须以 + 或者 - 开头
4.2在.h中声明的所有方法作用域都是public类型,不能更改
4.3 analysis
1 #import <Foundation/Foundation.h> 2 3 @interface Student : NSObject 4 5 @end
1> 看第3行,OC中使用关键字@interface来声明一个类,@interface后面紧跟着类名Student。
2> 类名Student后面的冒号":"表示继承,即第3行代码的意思是Student继承自NSObject。
3> 因为NSObject被声明在Foundation.h中,所以在第1行用#import包含了Foundation.h文件。
4> 第5行的@end表示类的声明结束了。@interface和@end是配套使用的。
4.4
1 #import "Student.h" 2 3 @implementation Student 4 5 @end
1> 看第3行,OC中使用关键字@implementation来实现一个类。@implementation后面紧跟的类名,表示究竟要实现哪一个类。
2> 因为Student这个类是声明在Student.h中的,所以在第1行用#import包含了Student.h文件。如果你不包含Student.h,第3行代码肯定报错,因为它根本不知道Student是个什么鬼东西。
3> 第5行的@end表示类的实现结束了。@implementation和@end是配套使用的。
4.5
前面我们定义了一个成员变量age,它的作用域是@protected,外界不能直接访问它。为了保证面向对象数据的封装性,我们可以提供age的get方法和set方法,让外界间接访问age。接下来在Student中添加age的get方法和set方法。
1.在Student.h中声明方法
1> 第18行声明了age的get方法,方法名就叫做age,OC建议get方法的名字跟成员变量保持一致(如果是在Java中,就应该叫做getAge)
2> 第18行最面的 - 表示这是一个动态方法( + 则表示静态方法)。age前面的(int)表示方法的返回值为int类型,方法的返回值和参数类型都需要用小括号()包住
3> 第21行声明了age的set方法,前面的 - 表示动态方法,(void)表示方法没有返回值
4> 在OC方法中,一个冒号:对应一个参数。由于第21行age的set方法接收一个int类型的参数,参数名为newAge,所以(int)newAge前面有一个冒号:
5> 一定要记住:一个冒号:对应一个参数,而且冒号:也是方法名的一部分。因此第21行set方法的方法名是setAge:,而不是setAge
再加大一下难度,假如增加一个方法可以同时设置age和height,那么就应该这样写:
1 - (void)setAge:(int)newAge andHeight:(float)newHeight;
* 这个方法是动态方法、没有返回值,接收2个参数,所以有2个冒号:
* 这个方法的方法名是setAge:andHeight:
* 其实andHeight是可以省略的,它只是为了让方法名念起来通顺一点,也让(float)newHeight前面的冒号:不那么孤单
4.6
前面已经定义了一个Student类,成员变量和方法都有了,接下来看一下怎么使用这个类创建对象。
由于OC程序的入口点是main函数,所以在main.m文件中演示Student类的使用。
先上完整代码
1.包含Student.h
因为要用到Student这个类,所以在第2行包含了它的头文件
#import "Student.h"
2.创建对象
1> 在Java中是使用关键字new来创建对象,比如new Student(),其实这句代码做了2件事:
- 给对象分配存储空间
- 调用Student的构造方法进行初始化
2> 在OC中创建对象也需要按顺序做上面所述的2件事
1)调用Student类的静态方法alloc分配存储空间
Student *stu = [Student alloc];
- OC是方法调用是用中括号[ ],方法调用者写在括号左侧,方法名写在括号右侧,中间留点空格。因此上面是调用了Student类的静态方法alloc。
- 上面调用的alloc方法会返回分配好内存的Student对象,在等号左边用了一个指向Student类型的指针变量stu来接收这个对象,注意stu左边的*号。所有OC对象都是用指针变量来接收的,如果你不了解指针,你记住下面这点就行了:利用类名定义一个变量时,类名后面一定要带个*号。
- alloc方法是这样声明的:
+ (id)alloc;
可以看到,它的返回值类型是id,这个id代表任何指针类型,你可以暂时理解为:id可以代表任何OC对象,类似于NSObject *。
2)调用Student对象的构造方法init进行初始化
前面调用alloc方法返回的Student对象stu是不能正常使用的,因为仅仅是分配了内存,并没有进行初始化,接下来调用对象的init方法进行初始化
stu = [stu init];
看清楚了,由于init是动态方法,所以这里使用stu变量来调用,并不是使用类名来调用。init会返回已经初始化完毕的对象,再次赋值给了stu变量。这时候的Student对象stu才能正常使用。
3)其实,我们最常见的做法是将alloc和init连起来使用:
Student *stu = [[Student alloc] init];
相信有面向对象开发经验的你一眼就能看懂了,在main.m完整代码的第7行。
3.销毁对象
由于OC不支持垃圾回收,因此当不再使用某个对象时,需要调用对象的release方法释放此对象。我们在第9行销毁了stu对象。
[stu release];
这个release方法在这里调用一次即可,不要觉得多调用多几次,对象就会释放地干净一点,这样做会很危险,容易造成野指针错误。
4.其他
1> 也可以调用静态方法new快速创建一个对象
1 Student *stu = [Student new]; 2 3 [stu release];
不过我们还是习惯使用alloc和init来创建对象
2> 前面我们调用了Student的alloc、init、new方法,但是你会发现Student.h中并没有声明这些方法,为什么能够调用呢?原因很简单,这些方法都是父类NSObject的,子类当然可以调用父类的方法。
4.7
前面已经成功创建了一个Student对象,接下来访问一下它的公共变量和方法。
1 #import <Foundation/Foundation.h> 2 #import "Student.h" 3 4 int main(int argc, const char * argv[]) 5 { 6 @autoreleasepool { 7 Student *stu = [[Student alloc] init]; 8 9 // 访问公共变量no 10 stu->no = 10; 11 12 // 调用setAge:方法设置变量age的值 13 [stu setAge:27]; 14 15 // 调用setAge:andHeight:方法同时设置变量age和height的值 16 [stu setAge:28 andHeight:1.88f]; 17 18 // 访问公共变量no 19 int no = stu->no; 20 // 调用age方法获取变量age的值 21 int age = [stu age]; 22 23 // 打印no和age的值 24 NSLog(@"no is %i and age is %i", no, age); 25 26 [stu release]; 27 } 28 return 0; 29 }
1.第7行创建了Student对象,第26行销毁了对象
2.第10行和第19行访问了Student对象的公共成员变量no,如果不是公共变量,不能像这样直接访问。注意访问方式:对象->成员变量
3.第13行调用了Student对象的setAge:方法,传入参数27修改了成员变量age的值
4.第16行调用了Student对象的setAge:andHeight:方法,同时修改了成员变量age和height的值
5.第21行调用了Student对象的age方法获取成员变量age的值
6.第24行输出了age和no的值,输出结果:
2013-04-06 21:54:56.221 第一个OC程序[1276:303] no is 10 and age is 28