OC-4-语法总结
来源:互联网 发布:青花瓷 知乎 编辑:程序博客网 时间:2024/05/15 11:53
传统的get和set方法
点语法的介绍和使用
对象.属性名
p.name= @"凤姐";
p.age= 12;
注意:此时(对象.属性名)并不是直接访问实例变量,而是Xcode看到点语法后,会自动帮我们替换为
[p setName:@“凤姐"];
[p setAge:12];
同理,对象.属性名在等号右侧,也会自动替换get方法
点语法:Xcode特性,Xcode帮我们做代码替换。在等号左侧为set方法,在等号右侧为get方法(设置值,还是取值)。
注意事项:
点语法的本质是方法调用,而不是访问成员变量。当使用点语法时,编译器会自动展开成相应地方法。切记点语法的本质是替换为相应地set和get方法,如果没有set和get方法,则不能够使用点语法。
@property关键字:省略方法的声明
@property是编译器指令,告诉编译器要做什么
@property 告诉编译器声明属性的访问器(getter和setter)方法
好处:免去手工书写get和set方法繁琐的代码
@property的用法:@property 类型名 名称;(最好是:去掉下划线的实例变量)
注意事项:1、实现get和set方法的声明
2、@property只能写在@interface 和@end之间
3、如果@property后面的类型一致,可以写在一起
@synthesize关键字:省略方法的实现
@synthesize也是编译器指令
@synthesize在.m文件中定义set和get方法的实现
@synthesize的用法:@synthesize 名称;(与上面的一样)
注意事项:1、@synthesize在@interface和@end之间
2、@synthesize后的名称必须在.h中声明
3、如果@synthesize后面的类型一致,可以写在一起。不一致也可以写在一起,但是不同类型需要区分。
@synthesize指定实例变量赋值
1、@synthesizename;//操作的是name,name有值
2、@synthesizeweight = _weight;//操作的是实例变量_weight,_weight有值
3、不指定赋值,会生成name。指定实例变量赋值后,会生成_weight,set赋值和get返回值同以前调用方法时的操作
@property增强使用
1、xcode4.4之后,可以只使用@property,而不使用@synthesize。
2、声明和实现了get和set方法,操作的是带有下划线的实例变量。
3、如果当前类没有下划线的实例变量,系统会帮助我们生成
//只需要@property语句
@propertyint age; //系统自动生成 int _age;
@propertyNSString *name; //系统自动生成 NSString*_name;
系统自动生成的变量,子类不能继承,完全私有化,且不可见。但是使用@property展开的方法,子类可以重写。
@property增强之后的get和set方法的重写:防止非法赋值,get和set方法只能重写一个
动态类型:程序直到执行时才能确定所述的类
静态类型:将一个变量定义为特定类的对象时,使用的是静态形态,编译时就知道所属的类
id类型及应用场景
1、NSObject访问子类
Animal*ani = [Animalnew];
[anirun];//动物会跑
Animal *ani2 = [Dog new];
[ani2 run];//多态
NSObject *obj = [Animal new];
[(Animal *)obj run];//NSObject访问子类
obj = [Dog new];
[(Dog *)obj run]; //访问子子类
Animal *ani2 = [Dog new];
[ani2 run];//多态
NSObject *obj = [Animal new];
[(Animal *)obj run];//NSObject访问子类
obj = [Dog new];
[(Dog *)obj run]; //访问子子类
//NSObject是所有类的基类,可以指向任何子类,指向时要强制转换
2、id类型
id类型是一种通用型指针,可以转换为任何类型,又称为万能指针
注意:在id的定义中,已经包装好了*号,id指针只能指向OS的对象
//id的使用
id obj2; //只能指向对象
obj2 = ani; //传一个对象
[obj2 run];
//NSObject和id都可以指向任何对象
//NSObject对象会进行编译时检查(需要强制类型转换)
//id不需要强制转换,id可以直接使用
id obj2; //只能指向对象
obj2 = ani; //传一个对象
[obj2 run];
//NSObject和id都可以指向任何对象
//NSObject对象会进行编译时检查(需要强制类型转换)
//id不需要强制转换,id可以直接使用
//编译器看到id以后,认为是动态类型,不检查类型
instancetype和id的异同:
1、相同点:都可以作为方法的返回类型
2、不同:1)instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象(只有运行时才知道)
2)instancetype只能作为返回值,不能像id那样为作为参数
3、动态类型
动态绑定:在objuect-c中,一个对象是否调用指定的方法不是有编译器决定而是由运行时决定,这种称为方法的动态绑定
动态类型检测方法:
对象在运行时获取其类型的能力称为内省。内省有多种方法实现。
1)判断类型
-(BOOL) isKandOfClass : classObj 判断实例对象是否是这个类或者这个类的子类的实例
Animal*ani = [Animalnew];
//ani 是否是Animal得实例对象
//ani 是否是Animal得实例对象
//动态类型检测:
//1、判断类型
//1) 使用格式:[对象isKindOfClass 类对象]
BOOL isInstance = [ani isKindOfClass:[Animalclass]];
NSLog(@"%d", isInstance);
-(BOOL) isMemberOfClass : classObj 判断是否是这个类的实例,不管是否是这个类的子类的实例
//2)使用格式:[对象isKindOfClass :类对象]
Dog *dog = [Dog new];
isInstance = [dog isMemberOfClass:[Animalclass]];
Dog *dog = [Dog new];
isInstance = [dog isMemberOfClass:[Animalclass]];
NSLog(@"%d", isInstance);
+(BOOL) isSubclassOfClass : classObj 判断类是否是指定类的子类
//3)使用格式:[类AisSubclassOfClass : 类B](类与类之间的关系)
//类A是否是类B的子类
BOOL isSub = [Dog isSubclassOfClass:[Animalclass]];
//通过对象来获取类对象
isSub = [[dog class]isSubclassOfClass:[aniclass]];
//通过对象来获取类对象
isSub = [[dog class]isSubclassOfClass:[aniclass]];
NSLog(@"%d", isSub);
2)指定方法响应的检测
- (BOOL)respondsToSelector:(SEL)aSelector; 判断对象能否响应指定的方法
//使用格式:[对象respondsToSelector :(SEL)]
SEL s1 = @selector(eat);//把eat包装为SEL类型
BOOL isRespond = [ani respondsToSelector:s1];
NSLog(@"%d", isRespond);
if (isRespond) {
[(Dog *)ani eat];
} else {
NSLog(@"不能调用此方法");
BOOL isRespond = [ani respondsToSelector:s1];
NSLog(@"%d", isRespond);
if (isRespond) {
[(Dog *)ani eat];
} else {
NSLog(@"不能调用此方法");
}
+ (BOOL)instancesRespondToSelector:(SEL)aSelector; 判断类能否响应指定的方法
//使用格式:[类instancesRespondToSelector : (SEL)]
isRespond = [DoginstancesRespondToSelector:s1];
isRespond = [DoginstancesRespondToSelector:s1];
NSLog(@"%d", isRespond);
3)应用selector指定的方法
响应无参方法
- (id)performSelector:(SEL)aSelector;
响应有参方法
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
Animal*ani = [Animalnew];
if ([ani respondsToSelector:@selector(eat)]) {
//[(Dog *)ani eat];
//不写上面的形式,响应无参方法
[ani performSelector:@selector(eat)];
if ([ani respondsToSelector:@selector(eat)]) {
//[(Dog *)ani eat];
//不写上面的形式,响应无参方法
[ani performSelector:@selector(eat)];
//响应有参方法
[aniperformSelector:@selector(eat:) withObject:@"骨头"];
}else {
NSLog(@"不能调用此方法");
NSLog(@"不能调用此方法");
}
构造方法
构造方法:用来初始化对象的方法,是对象方法,-开头
重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
1)构造方法的调用
new可以拆为alloc分配空间和init初始化对象,然后返回对象首地址
OC中的构造方法:给对象进行初始化的方法(init方法:对象方法,该方法返回的是一个对象(调用init的对象))
2)重写构造方法
//子类把父类的init覆盖,默认先执行子类
- (instancetype)init {
//先让父类把父类原来做的事情做完
self = [super init];
//判断父类是否初始化成功,成功不为空
if (self) {
//此处写子类的代码内容
_age = 10;
}
return self;//self指代的是方法的调用者
- (instancetype)init {
//先让父类把父类原来做的事情做完
self = [super init];
//判断父类是否初始化成功,成功不为空
if (self) {
//此处写子类的代码内容
_age = 10;
}
return self;//self指代的是方法的调用者
}
问题:
1、[super init]的作用
面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化
2、self为什么要赋值为[super init]
简单的说是为了防止父类的初始化方法release掉了self指向的空间,并重新alloc了一块空间。这时的话,[super init]可能alloc失败,这时就不再执行if中的语句。
3、super作为消息接收者的实质
super并不是真正的指针,[super message]的实质是由self来接受父类的message,需要注意的是,[super message]中,message方法出现的self为[super message]语境中的self,即子类实例。
自定义构造方法
1)自定义构造方法的规范
1、一定是对象方法,以-开头
2、返回值一般是id类型
3、方法名一般以initWith开头
2)自定义构造方法使用
#import"Person.h"
@implementation Person
//-(instancetype)init{
// if (self = [super init]) {
// _name = @"凤姐";
// _age = 18;
// }
// return self;
//}//这样就写死了
-(instancetype)initWithName:(NSString*)name andAge:(int)age{
if (self = [super init]) {
_name = name;
_age = age;
}
return self;
}
@implementation Person
//-(instancetype)init{
// if (self = [super init]) {
// _name = @"凤姐";
// _age = 18;
// }
// return self;
//}//这样就写死了
-(instancetype)initWithName:(NSString*)name andAge:(int)age{
if (self = [super init]) {
_name = name;
_age = age;
}
return self;
}
@end
//用指定的值进行初始化
//创建对象时,用我们制定的名字和年龄进行初始化
Person *p1 = [[Person alloc] initWithName:@"陈子超"andAge:18];
//创建对象时,用我们制定的名字和年龄进行初始化
Person *p1 = [[Person alloc] initWithName:@"陈子超"andAge:18];
NSLog(@"%@,%d", p1.name, p1.age);
//创建一个学生类,继承人类,要求初始化就设置了姓名,年龄,学号
#import"Student.h"
@implementation Student
-(instancetype)initWithName:(NSString*)name andAge:(int)age andIdNum:(int)idNum{
if (self = [super initWithName:name andAge:age]) {//初始化父类的initWith
_idNum = idNum;
}
return self;
}
@implementation Student
-(instancetype)initWithName:(NSString*)name andAge:(int)age andIdNum:(int)idNum{
if (self = [super initWithName:name andAge:age]) {//初始化父类的initWith
_idNum = idNum;
}
return self;
}
@end
Student*stu = [[Studentalloc]initWithName:@"陈子超"andAge:24andIdNum:18];
NSLog(@"%@,%d,%d", stu.name, stu.age, stu.idNum);
0 0
- OC-4-语法总结
- OC语法总结
- OC语法总结
- OC新语法总结
- OC语法总结
- OC语法总结
- OC语法总结
- OC 语法总结
- OC特有语法总结
- OC语法总结
- oc总结 --oc基础语法相关知识
- oc总结 --oc基础语法相关知识
- oc总结 --oc基础语法相关知识
- OC总结-block语法
- 5.OC语法糖总结-@[],@{},@()
- OC语法基础:NSURLConnection总结
- OC中语法糖,最新语法总结
- OC中语法糖,最新语法总结
- 【Java】javaIO之用FileReader和writer读写文本文件
- 《寒江独钓》内核学习笔记(1)-- IRP - .Little Hann
- OC-3-面向对象
- C++重载类型转换操作符
- Python 值传递和引用传递
- OC-4-语法总结
- MyEclipse里运行Tomcat后,Console窗口里中文显示乱码
- 【Java】javaIO之用随机流读写文件
- OC+1-内存管理
- UIAlertController
- OC+2-ARC-Category-block
- 微信内置浏览器音频直播
- OC+3-protocol
- Tomcat【4】(tomcat在eclipse的配置)