黑马程序员-OC回顾-语法总结
来源:互联网 发布:mac mini nas 方案 编辑:程序博客网 时间:2024/06/08 14:48
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、点语法
1、点语法介绍和使用
Dog *d=[Dog new];
d.age=3; 等价于[d setAge:3];
int a = d.age;等价于[d age];
注意:
1)d.age=3和[d setAge:3]是完全等价的。这里d.age并不是直接访问d对象的成员变量age,而是Xcode遇到d.age=3的时候会自动将代码转换成[d setAge:3]
2)在int a = d.age中,也并不是直接访问d对象的成员变量age,而是Xcode遇到int a = d.age的时候自动转换成int a = [a age];
3)OC点语法的本质是方法调用,不是直接访问成员变量。
至于这个点语法代表的是get方法还是set方法,却绝与你是在取值还是设值
2、点语法验证
只需要在get和set方法中用NSLog打印内容测试
//// main.m// 3-点语法介绍#import <Foundation/Foundation.h>#import "Dog.h"int main(int argc, const char * argv[]) { @autoreleasepool { Dog *d=[Dog new]; d.age=3; int a = d.age; NSLog(@"狗的狗龄是:%d",a); } return 0;}
//// Dog.h#import <Foundation/Foundation.h>@interface Dog : NSObject{ int _age;}-(void)setAge:(int) age;-(int)age;@end
//// Dog.m#import "Dog.h"@implementation Dog-(void)setAge:(int) age{ NSLog(@"调用了set方法!"); _age=age;}-(int)age{ NSLog(@"调用了get方法!!"); return _age;}@end
运行结果:
2015-10-26 14:05:47.372 3-点语法介绍[718:50338] 调用了set方法!2015-10-26 14:05:47.372 3-点语法介绍[718:50338] 调用了get方法!!2015-10-26 14:05:47.372 3-点语法介绍[718:50338] 狗的狗龄是:3Program ended with exit code: 0
3、点语法使用注意
1)点语法陷阱
(1)OC中有个self关键字
-(void)setAge:(int) newAge
{
self.age = newAge;
}
这是错误的,会造成死循环。
(2)同样,return self.age也是错误的。
2)点语法注意
点语法的本质是方法的调用,而不是直接访问成员变量,当使用点语法是,Xcode会自动转换成相应地方法。
切记点语法的本质是转换成相应地set和get方法,如果没有set和get方法,则不能使用点语法。
二、@property关键字
1、基本概念
@property是编译器的指令
编译器指令是用来告诉编译器要做什么
@property告诉编译器声明属性的访问器(getter/setter)方法
好处:
免去我们手工书写get和set方法繁琐的代码。
2、@property用法
@property 类型名 方法名
例如:
@property int age;
相当于进行了age的set个get方法的声明
-(void)setAge:(int) age;
-(void)age;
3、@property使用注意
在Xcode4.4之前:
@property只能写在@interface和@end中,
@property用来自动生成成员变量的get和set方法声明
告诉property要生成的get、set方法声明的成员变量的类型是什么
告诉property要生成的get、set方法是哪个属性的,属性名称去掉下划线
如果加下划线的话,会于实例变量同名,就需要self->调用
三、@synthesize关键字
1、@synthesize用法
@synthesize 方法名
@synthesize age:表示生成.h中变量age的get和set方法的实现。
使用@synthesize的话,变量名要先在.h文件中声明。
@property和@synthesize这两个必须是配合使用的
正确用法:
1)先定义变量 int age;
2)使用@property age;声明方法
3)使用@synthesize; 实现方法
2、注意事项
@property和@synthesize搭配使用,用于简化set和get方法的定义和实现。
四、@synthesize指定实例变量赋值
@property int a;
@synthesize a=_b;
表示永a的get和set方法,修改属性b的值
相当于下面的代码:
-(void)setA:(int) a{ _b=a;}-(int)a;{return _b;}
//// main.m#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p=[Person new]; p.age=18; p.name=@"张三丰"; [p test]; NSLog(@"姓名:%@,年龄:%d",p.name,p.age); } return 0;}
//// Person.h#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age; NSString * _name;}@property int age;@property NSString* name;-(void)test;@end
//// Person.m#import "Person.h"@implementation Person@synthesize age=_age ;@synthesize name=_name;-(void)test{ NSLog(@"age=%d,name=%@",_age,_name);// NSLog(@"age=%d,name=%@",age,name); }@end
运行结果:
2015-10-26 14:05:10.300 8-@synthesize指定实例变量赋值[714:49965] age=18,name=张三丰2015-10-26 14:05:10.300 8-@synthesize指定实例变量赋值[714:49965] 姓名:张三丰,年龄:18Program ended with exit code: 0
五、@property增强使用
Xcode4.4版本以后支持的
只使用@property进行声明,类自动帮你实现。
Xcode4.4版本以后property作了增强,帮助我们自动生成get/set方法的声明
操作的是带有下划线的实例变量
如果没有手动声明成员变量,property会在.m文件中自动帮我们生成一个_开头的成员变量,此时生成的变量是私有变量,子类无法继承和访问。
.h文件中
@property int score;
.m文件中
首先生成一个_score的变量(该变量是私有的)
-(void)setScore:(int) score{_score= score;}-(void)score{return _score;}
//// main.m#import <Foundation/Foundation.h>#import "Person.h"#import "Man.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p=[Person new]; p.age=18; p.name=@"张三丰"; [p test]; Man *m=[Man new]; [m test1];//可以使用,表示子类继承了父类的_age,但是_name不行。 } return 0;}
//// Person.h#import <Foundation/Foundation.h>@interface Person : NSObject{ int _age;}-(void)test;@property int age;@property NSString* name;@end
//// Person.m#import "Person.h"@implementation Person-(void)test{ NSLog(@"_name=%@,_age=%d",_name,_age);}@end
//// Man.h#import "Person.h"@interface Man : Person-(void)test1;@end
//// Man.m#import "Man.h"@implementation Man-(void)test1{// NSLog(@"_name=%@",_name);// 上面的语句是错误的,_name是由@property自动生成的,是私有变量// 不能被子类继承和使用,如果想时候,要像_age一样在.h文件中手动声明。 NSLog(@"_age=%d",_age);}@end
运行结果:
2015-10-26 14:08:38.308 9-@property增强使用[726:51846] _name=张三丰,_age=182015-10-26 14:08:38.309 9-@property增强使用[726:51846] _age=0Program ended with exit code: 0
六、@property增强下重写get和set方法
手动实现:
1、如果手动实现了set方法,那么编译器就只生成get方法和成员变量。
2、如果手动实现了get方法,那么编译器就只生成set方法和成员变量。
3、如果set和get方法都是手动实现的,那么编译器将不会生成成员变量,并且报错。
//// main.m#import <Foundation/Foundation.h>#import "Person.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p=[Person new]; p.age=-18; p.name=@""; [p test]; } return 0;}
//// Person.h#import <Foundation/Foundation.h>@interface Person : NSObject@property int age;@property NSString* name;-(void)test;@end
//// Person.m#import "Person.h"@implementation Person-(void)setAge:(int)age{ if (age>0) { _age=age; } else { _age=0; }}-(void)setName:(NSString *)name{ if ([name length]>0) { _name=name; } else { NSLog(@"名字不能为空!"); }}-(void)test{ NSLog(@"_name=%@,_age=%d",_name,_age);}@end
运行结果:
2015-10-26 14:09:55.002 10-@property增强下的重写get和set方法[730:52649] 名字不能为空!2015-10-26 14:09:55.003 10-@property增强下的重写get和set方法[730:52649] _name=(null),_age=0Program ended with exit code: 0
七、动态类型和静态类型
1、概念
多态:允许不同的类定义相同的方法。
动态类型:程序直到执行时才能确定所属的类。
静态类型:将一个变量定义为特定类的对象时,使用的是静态形态。
将一个变量定义成特定类的对象是,使用的是静态类型,在编译的时候就知道这个变量所属的类,这个变量总是存储特定类的对象。
使用静态类型是,编译器尽可能的确保变量的用法在程序中始终保持一致,编译器能够通过减产来确定应用于对象的方法是由该类定义的或者由该类继承的,否则就会显示警告。
静态类型能够更好的在程序编译阶段就指出错误。并且使用静态类型可以提高程序的可读性。
2、为什么要有动态类型
有动态类型,才会有多态。
多态的出现是为了让不同的类能使用同名的方法。
这会让程序的可读性大大提高,也降低了变成难度。
编译和运行检查
因为存储在id变量中的对象类型在编译的时候是无法确定的,所以一些事情是需要在运行时才能够确定。
八、id类型及应用场景
1、用NSObject访问子类对象方法
需要强制类型转换,是静态类型
NSObject *obj = [Cat new];
[(cat *)obj run];
2、id类型
id是动态类型
程序只有在运行时才能确定它的具体类型。是指向哪个对象。
id是一种通用的对象类型,它可以用来存储属于任何类的对象,也可以理解为万能指针。
在id的定义中,已经有了*号。
id指针只能指向OC的对象。
id类型的定义
Typedef struct objc object{
Class isa;
} *id;
局限性:调用一个不存在的方法,编译器会马上报错。
iOS5之后推出了instancetype类型
1)相同点
都可以作为方法的返回类型。
2)不同点
(1)instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
(2)instancetype只能作为返回值,不能像id那样作为参数
3、id类型应用场景
<pre name="code" class="objc">Man *man=[Man new]; id obj = man; [obj run];
九、动态类型检测
1、动态绑定
在OC中,一个对象是否调用指定的方法不是编译器决定而是由运行时决定。
这被称作是方法的动态绑定。
2、动态类型检测方法
对象在运行是获取其类型的能力称为内省。
内省可以有多种方法实现。
1)判断类型
-(BOOL) isKindOfClass: classObj
判断实例对象是否是这个类或者这个类的子类的实例。
判断实例对象是否是另一个类类型
代码:
Person *p=[Person new]; BOOL b1=[p isKindOfClass:[Person class]]; BOOL b2=[man isKindOfClass:[Person class]]; NSLog(@"b1 = %d",b1); NSLog(@"b2 = %d”,b2);运行结果:2015-10-25 19:41:07.696 12-id类型应用场景[864:68082] b1 = 12015-10-25 19:41:07.696 12-id类型应用场景[864:68082] b2 = 1
b1=1说明p是person类的对象。
b2=1说明man是Person子类Man类的对象。
-(BOOL) isMemberOfClass: classObj
判断是否是这个类的实例,不管是否是这个类的子类的实例。
代码: BOOL b3=[p isMemberOfClass:[Person class]]; BOOL b4=[man isMemberOfClass:[Person class]]; NSLog(@"b3 = %d",b3); NSLog(@"b4 = %d",b4);运行结果:2015-10-25 19:45:54.712 12-id类型应用场景[872:69227] b3 = 12015-10-25 19:45:54.712 12-id类型应用场景[872:69227] b4 = 0
b3=1说明p是Person类的实例。
b4=0说明man不是Person类的实例。
+(BOOL) isSubclassOfClass:classObj
判断类是否是指定类的子类
代码:
BOOL b5=[Man isSubclassOfClass:[Person class]]; BOOL b6=[Person isSubclassOfClass:[Man class]]; NSLog(@"b5 = %d",b5); NSLog(@"b6 = %d”,b6);运行结果:2015-10-25 19:51:39.029 12-id类型应用场景[888:70645] b5 = 12015-10-25 19:51:39.029 12-id类型应用场景[888:70645] b6 = 0
结果和两个类的顺序还有关系,所以,b5=1而b6=0 。
//// main.m#import <Foundation/Foundation.h>#import "Man.h"int main(int argc, const char * argv[]) { @autoreleasepool { Man *man=[Man new]; id obj = man; [obj run]; Person *p=[Person new]; BOOL b1=[p isKindOfClass:[Person class]]; BOOL b2=[man isKindOfClass:[Person class]]; NSLog(@"b1 = %d",b1); NSLog(@"b2 = %d",b2); BOOL b3=[p isMemberOfClass:[Person class]]; BOOL b4=[man isMemberOfClass:[Person class]]; NSLog(@"b3 = %d",b3); NSLog(@"b4 = %d",b4); BOOL b5=[Man isSubclassOfClass:[Person class]]; BOOL b6=[Person isSubclassOfClass:[Man class]]; NSLog(@"b5 = %d",b5); NSLog(@"b6 = %d",b6); } return 0;}//// Person.h#import <Foundation/Foundation.h>@interface Person : NSObject-(void)run;@end//// Person.m#import "Person.h"@implementation Person-(void)run{ NSLog(@"人在跑!");}@end//// Man.h#import "Person.h"@interface Man : Person-(void)run;@end//// Man.m#import "Man.h"@implementation Man-(void)run{ NSLog(@"男人在跑!");}@end运行结果:2015-10-26 14:12:20.767 12-id类型应用场景[742:54135] 男人在跑!2015-10-26 14:12:20.768 12-id类型应用场景[742:54135] b1 = 12015-10-26 14:12:20.768 12-id类型应用场景[742:54135] b2 = 12015-10-26 14:12:20.768 12-id类型应用场景[742:54135] b3 = 12015-10-26 14:12:20.768 12-id类型应用场景[742:54135] b4 = 02015-10-26 14:12:20.768 12-id类型应用场景[742:54135] b5 = 12015-10-26 14:12:20.768 12-id类型应用场景[742:54135] b6 = 0Program ended with exit code: 0
十、判断对象能否响应指定的方法
1、-(BOOL) respondsToSelector: selector
判断实例是否有这样的方法或者说是否能响应方法
例如:
//对象dog能响应run和eat方法。 //run方法是从父类继承而来。 BOOL b1=[dog respondsToSelector:@selector(eat)]; BOOL b2=[dog respondsToSelector:s2]; NSLog(@"b1 = %d",b1); NSLog(@"b2 = %d",b2);运行结果:2015-10-25 20:26:42.761 14-判断对象是否能响应指定的方法[953:77675] b1 = 12015-10-25 20:26:42.762 14-判断对象是否能响应指定的方法[953:77675] b2 = 1 //对象dog不能响应test方法 SEL s3 = @selector(test); BOOL b3=[dog respondsToSelector:s3]; NSLog(@"b3 = %d",b3);运行结果:2015-10-25 20:26:42.762 14-判断对象是否能响应指定的方法[953:77675] b3 = 0
2、+(BOOL) instancesRespondToSelector:selector
判断类是否有这个方法。此方法是类方法。
用来判断类里是否有某个对象方法,不是判断类方法。
//判断类是否有这个方法。 BOOL b4=[Dog instancesRespondToSelector:s2]; NSLog(@"b4 = %d”,b4);结果:2015-10-25 20:33:06.007 14-判断对象是否能响应指定的方法[970:79368] b4 = 1
十一、响应方法
1、没有参数方法
-(id) performSelector:selector
2、一个参数方法
-(id) performSelector:selector withObject:object
3、两个参数的方法
-(id) performSelector:selector withObject:object1 withObject:object2
应用selector指定的方法 NSObject的方法
Dog *dog=[Dog new]; if ([dog respondsToSelector:@selector(eat)]) { [dog performSelector:@selector(eat)];//无参数方法 } else { NSLog(@"对象不能调用此方法!!!"); } //一个参数的方法 [dog performSelector:@selector(eat:) withObject:@"骨头"]; //两个参数的方法。 [dog performSelector:@selector(eat:andfoodName:) withObject:@"旺财" withObject:@"骨头"];运行结果:2015-10-25 21:03:07.283 15-响应方法[1021:87360] 狗在吃东西!!!2015-10-25 21:03:07.284 15-响应方法[1021:87360] 狗正在吃骨头2015-10-25 21:03:07.284 15-响应方法[1021:87360] 旺财正在吃骨头
十二、构造方法
1、构造方法的概念
构造方法:
用来初始化对象的方法,是个对象方法,-开头。
重写构造方法的目的:
为了让对象创建出来,成员变量就会有一些固定的值。
构造方法的调用
完整地创建一个可用的对象:
Person *p = [Person new];
new方法的内部会分别调用两个方法来完成3件事情:
1)使用alloc方法来分配存储空间(返回分配的对象);
2)使用init方法来对对象进行初始化;
3)返回对象的内存地址。
可以把new方法拆开如下:
1)调用类方法+alloc分配存储空间,返回未经初始化的对象
Peroson *p1=[Person alloc];
2)调用对象方法-init进行初始化,返回对象本身
Person *p2 = [p1 init];
3)以上两个过程整合为一句:
Person *p = [[Person alloc] init];
说明:
1)init方法就是构造方法。
用来初始化对象的方法,称为构造初始化。这是一个对象方法。
默认初始化完毕后,所有成员变量的值都是0.
2)alloc
向某个类发送alloc消息的结果
为该类分配内存,以存放该类的全部实力变量
还将这块内存区域全部初始化为0.
注意:
一个刚刚分配的独享并不能立即使用
需要先初始化该对象,然后才能使用它
但由于未进行初始化,随后可能出现一些不可预测的行为。
2、重写构造方法
格式:
-(id) init{ self = [super init]; if(self) { //为子类增加属性进行初始化 }return self;}
1)[super init]的作用:先调用父类的初始化方法,对从父类继承过来的成员变量进行初始化。
初始化完成之后,返回当前的对象指针。
2)self为什么要赋值为[super init]
为了防止父类的初始化方法释放掉self指向的空间并重新alloc了一块空间(可能性很小)。这时的话,[super init]可能alloc失败,这时就不再执行if中的语句。
3)super是调用父类方法。
4)为什么要加if判断:
基类里面是不需要这个的,都是在子类里面猜用得到。
[super init]是使用父类进行初始化,看看父类能不能被初始化,如果不能被初始化,子类就没法继承父类的属性和方法了。这个类就没有意义了,不能拥有父类的属性。所以加if来判断,不能继承的话,就直接返回空对象(没有意义)。
构造方法使用注意:
1)子类拥有的成员变量包括自己的成员变量以及从父类继承而来的成员变量,在重写构造方法的时候应该首先对从父类继承而来的成员变量先进行初始化。
2)原则:先初始化父类的,再初始化子类的。
3)重写构造方法的目的:为了让对象方法一创建出来,成员变量就会有一些固定的值。
4)注意点:
(1)先调用父类的构造方法[super init];
(2)再进行子类内部成员变量的初始化。
3、应用
1)需求1:
创建一个人的类,默认年龄10岁
需求2:
让学生继承人类,要求学生对象初始化之后,年龄是10,学号是1.
//主函数#import <Foundation/Foundation.h>#import "Person.h"#import "Student.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p=[Person new]; NSLog(@"年龄:%d",p.age); Student *stu = [[Student alloc] init]; NSLog(@"学号:%d,年龄:%d",stu.n,stu.age); } return 0;}
//Person类声明#import <Foundation/Foundation.h>@interface Person : NSObject@property int age;@end
//Person类的实现#import "Person.h"@implementation Person-(instancetype)init{ self = [super init]; if (self) { _age=10; } return self;}@end
//// Student.h#import "Person.h"@interface Student : Person@property int n;@end
//// Student.m#import "Student.h"@implementation Student-(instancetype)init{ self = [super init];//如果没有这句话,_age又会变成0. if (self) { _n = 1; } return self;}@end
运行结果:
2015-10-26 14:18:58.840 17-重写构造方法[752:57175] 年龄:102015-10-26 14:18:58.840 17-重写构造方法[752:57175] 学号:1,年龄:10Program ended with exit code: 0
2)思考&实现
现在有20个特种兵,特种兵随时随地都拥有一把枪,都可以开火
/* 现在有20个特种兵,特种兵随时随地都拥有一把枪,都可以开火 */// 主函数#import <Foundation/Foundation.h>#import "Soilder.h"int main(int argc, const char * argv[]) { @autoreleasepool { for (int i =0; i<20; i++) { Soilder *s_i = [Soilder new]; [s_i useGun]; } } return 0;}
//// Gun类的声明#import <Foundation/Foundation.h>@interface Gun : NSObject@property int bulletCount;-(void)shoot;@end
//// Gun类的实现#import "Gun.h"@implementation Gun-(void)shoot{ if(_bulletCount>0){ _bulletCount--; NSLog(@"枪在突突突的射击!剩余子弹数%d",_bulletCount); }else{ NSLog(@"没有子弹了!"); }}//重写构造方法,是每把枪创建的时候自带3发子弹。-(instancetype) init{ if (self=[super init]) { _bulletCount=3; } return self;}@end
//// Soilder类的声明#import <Foundation/Foundation.h>#import "Gun.h"@interface Soilder : NSObject@property Gun * gun;-(void)useGun;@end
//// Soilder类的实现#import "Soilder.h"@implementation Soilder//重写构造方法,使每个士兵创建的时候就有一把枪-(instancetype) init{ if (self=[super init]) { Gun *gun = [Gun new]; _gun = gun; } return self;}-(void)useGun{ [_gun shoot];}@end运行结果:
2015-10-26 14:20:29.100 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.101 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.102 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.102 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.102 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.102 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数22015-10-26 14:20:29.102 18-重写构造方法应用场景[764:58060] 枪在突突突的射击!剩余子弹数2Program ended with exit code: 0
4、自定义构造方法
1)自定义构造方法的规范
(1)一定是对象方法,以减号开头。
(2)返回值是instancetype(id)类型
(3)方法名一定以initWith开头
2)自定义构造方法的代码实现
思考&实现
1)给Person类定义一个构造方法,自定义姓名和年龄
2)给Student类定义一个构造方法,自定义姓名、年龄和学号。
//主函数#import <Foundation/Foundation.h>#import "Person.h"#import "Student.h"int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [[Person alloc] initWith:@"杨过" andAge:21]; NSLog(@"姓名:%@,年龄:%d",p.name,p.age); Student *stu = [[Student alloc] initWith:@"小龙女" andAge:18 andNo:21]; NSLog(@"姓名:%@,年龄:%d,学号:%d",stu.name,stu.age,stu.no); } return 0;}
//// Person类的声明#import <Foundation/Foundation.h>@interface Person : NSObject@property int age;@property NSString* name;-(instancetype) initWith:(NSString*) name andAge:(int) age;@end
//// Personlei#import "Person.h"@implementation Person-(instancetype) initWith:(NSString*) name andAge:(int) age{ if (self = [super init]) { _age = age; _name = name; } return self;}@end
//// Student类的声明#import "Person.h"@interface Student : Person@property int no;-(instancetype) initWith:(NSString*) name andAge:(int)age andNo:(int) no;@end
//// Student.m#import "Student.h"#import "Person.h"@implementation Student-(instancetype) initWith:(NSString*) name andAge:(int)age andNo:(int) no{ self = [super initWith:name andAge:age]; if (self) { _no = no; } return self;}@end
运行结果:
2015-10-26 14:22:55.137 19-自定义构造方法[768:59467] 姓名:杨过,年龄:212015-10-26 14:22:55.138 19-自定义构造方法[768:59467] 姓名:小龙女,年龄:18,学号:21Program ended with exit code: 0
3)自定义构造方法的使用注意
(1)自己做自己的事情
(2)父类的方法教给父类的对象(super)来处理,子类的方法处理子类特有的属性。
- 黑马程序员-OC回顾-语法总结
- 黑马程序员-OC回顾-基础语法
- 黑马程序员-OC回顾-基础语法(二)
- 黑马程序员-OC基本语法总结
- 黑马程序员------OC基础-----基础语法总结
- 黑马程序员:OC基本语法
- 黑马程序员-OC基本语法
- [黑马程序员][OC]点语法
- 黑马程序员----OC核心语法
- 黑马程序员 OC语法补充
- 黑马程序员---OC--特有语法
- 黑马程序员--OC基本语法
- 黑马程序员-OC-点语法
- 黑马程序员--OC-点语法
- 黑马程序员.............OC基础语法
- 黑马程序员-------OC----点语法
- 黑马程序员-OC回顾-对象特性
- 黑马程序员-OC回顾-面向对象
- XCode快捷键
- android自定义的toast样式
- HDOJ 题目4000 Fruit Ninja(树状数组)
- 斐波那契数列的算法实现 —— python
- C语言strcat()
- 黑马程序员-OC回顾-语法总结
- nodejs安装express时丢人了
- C++顺序容器vector,deque,list
- 惯性力的数学推导
- [oracle]数据库备份还原操作详细操作
- 如何解决Error: Can't create a new thread (errno 12)
- 从头认识java-4.5 对象的清理(finalize())
- NVIDIA的黑科技3:VXGI体素全局光照
- mysql更新查新乱码问题