命名:set + 成员变量名称,且后者首字母大写,返回值一定要是void,形参不能跟成员变量名称一致,可以在前面+new.
#import <Foundation/Foundation.h>
@interface Student : NSObject {
int _age;
}
- (void)study;
- (void)setAge : (int)newAge;
- (int)age;
@end
@implementation Student
- (void)study{
NSLog(@"%d岁的学生在学习",_age);
}
- (void)setAge : (int)age{
if (age <= 0){
age = 1;
}
_age = age;
}
- (int)age{
return _age;
}
@end
int main(){
Student *stu = [Student new];
[stu setAge : -15];
NSLog(@"学生现在%d岁",[stu
age]);
[stu study];
}
十三.弱语法
是用一个对象并不存在的方法,编译和链接均只是警告,而不是报错。
报错:
'NSInvalidArgumentException', reason: '-[Person test]: unrecognized selector sent to instance 0x7faf28c0cc50'
给对象Person发送了一个不能识别的消息test.
OC的方法是动态检测,在运行过程中才会检测对象有没有实现相应的方法。
声明(interface)是可以不写的,可以直接写实现并且继承NSObject(在main以前才可执行),但是实际中不这么写。
十四.类方法
与之对应的是对象方法。
类方法以+开头,由于不用创建对象,直接从类的存储空间执行,可以提升性能。
只能由类调用。允许类方法与对象方法同名,类方法内不能访问成员变量。
类方法的好处:不依赖于对象,执行效率高,能用类方法尽量用类方法。
要防止死循环(无限递归)。
十五.self关键字
self是一个指针,指向方法调用者。
如self->_age来访问成员变量。
或者[self <method>]在类内执行方法。
注意,在类方法内也可以使用self!!!,这时候self代表类。
注意事项:
也要防止死循环(无限递归)。注意分析self指向的是对象还是类。
谁调用了当前方法,self就指向谁 。
十六.面向对象三大特性之继承
被继承的类称为父类(super),继承别人的类称为子类。
使用 : 来继承,由于默认的访问参数为protected,因此可以被全部继承。
例如NSObject是根类,包含了创建对象等方法。
特殊:NSProxy不是继承自NSObject,它也是一个根类。
注意事项:
父类必须声明在子类之前。
不允许子类和父类具有想通名称的成员变量。
调用对象,优先去对象所在的类找,找不到再去父类找。(每个类内都有superclass指针,也有isa指针指向类的存储空间)
继承的缺点:耦合性太强。
区分组合和继承:
例如Student要有Score的属性,应该把Score作为Student的一个成员变量 xxx拥有xx。
如果Dog要有Animal的属性,应该让Dog继承Animal。 xxx是xx。
访问父类,使用super。既可以访问对象方法,也可以调用类方法。
super处于对象(类)方法中,就会调用父类的对象(类)方法。
常见场景:
常常是在子类重写的方法中再调用父类的方法。
十七.面向对象三大特性多态
多态:父类指针指向子类对象。
例如Dog类继承了Animal类
Animal *a = [Dog new];
假设Animal和Dog都有eat方法
[a eat];调用的是子类Dog的方法,会动态检测a指针指向的对象是什么类型,会调用真实类型的方法。
由于NSObject是根类,甚至可以使用NSObject *n = [Dog new];
多态的好处:
例如有feed方法用来喂动物,传入Animal指针,这样就可以处理各种继承子Animal的对象。
void feed(Animal *a){
[a eat];
}
多态的局限性:
父类类型的指针变量不能用来调用子类方法(可以调用成功,但是语法不规范),如果一定要调用,先进行类型转换。
十八.NSString
创建字符串:
NSString *str = @“string”;
输出字符串用%@:
NSLog(@“xxx%@“,str);
创建字符串的另一种方式
str = [NSString stringWithFormat : @“xxxxxx %d”, <var>];