OC中的封装、继承、多态
1)一个类中有多个属性,而对于属性,为了安全不应该给属性修饰@public,默认的是有@protect修饰符修饰的。而被@protect修饰符修饰的属性只能被在本类和子类中的对象通过箭头访问。那么想在别处需要使用这个属性,就应该给每个属性封装一个setter和getter方法,如果想使用这个属性的时候,直接调用setter和getter方法就可以了。
属性的setter方法是用于属性的赋值,而getter方法是取值。setter方法:- (返回值类型) set去掉下划线且首字母大写的属性名:(参数的返回值类型)去掉下划线的属性名;getter方法:- (void) 去掉下划线的属性名;
关于在属性的setter方法中给属性赋值是不能随便赋值的,对于基本数据类型,直接赋值就可以了,比如属性是 int age; _age = age; 如果是属性是OC对象,就不能直接赋值,因为OC对象本身就是个指针,存在堆区中,存得是一个地址。比如说NSString *_name;_name存在堆区中,如果给_name赋值 _name = @“小逗子”; 那么这个_name存的是@“小逗子”字符串的地址,而@“小逗子”是存在常量区的,常量区的数据一旦创建直到程序运行结束之前,是不会被回收的,因此给OC对象属性赋值之前,得先判断你要赋的那个值是存在了,如果不存在就先release掉之前得那个对象。比如:
- (void)setBookName:(Book *)bookName
{
if(_bookName != bookName)
{
[_bookName release];
_bookName = [bookName retain];
}
}
如果是NSString类型的对象,NSString类型的对象的引用计数器里值非常大,而retain方法的作用就是把对象中的引用计数器+1,而对于NSString类型的对象是没用的,把retain换成copy比较好,比如:
- (void)setBookName:(NSString *)bookName
{
if(_bookName != bookName)
{
[_bookName release];
_bookName = [bookName copy];
}
}
然而在Xcode中有利用@property关键字来修饰属性就可以自动生成setter和getter方法,不需要我们自己再去给一个一个的属性写setter和getter方法了。@property的语法:@property(参数列表) (属性类型) 去掉下划线的属性名;
其中@property的参数中同一组的参数最多只能出现1个,其中atomic与nonatomic是一组,推荐nonatomic因为nonatomic运行的效率比较高;retain、strong、copy、assign是同一组,OC对象在MRC模式下用retain,在ARC模式下用strong,如果是NSString类型对象用copy,使用retain、strong、copy这三个参数产生的是标准的setter方法,基本数据类型不管是MRC模式还是ARC模式下都用assign,使用assign是在setter方法中直接给属性赋值,默认值是assign;readwrite与readonly是同一组,readwrite是同时生成setter和getter方法,而readonly是只生成getter方法,默认readwrite。
2)继承是子类可以继承父类里的所有属性和方法,也就是说如果B类继承A类,A类里的所有的属性和方法,在B类中不需要重新定义,直接就可以使用A类中的属性和方法。如果子类在有父类的属性和方法的基础上想拥有一些父类没有的属性和方法,可以自己定义,但是子类中自己定义的属性和方法,在父类中不可以使用。继承的语法如下:
@interface 儿子类的类名 : 父亲类的类名
{
属性
}
方法的声明
@end
@implementation 儿子类名
方法的实现.
@end
这个时候,儿子类就拥有了父亲类中定义的所有的成员.
几个术语.
@interface Student : Person
Student类从Person类继承. Student是Person的子类 Person是Student的父类.
Student类从Person类派生. Student类是Person类的派生类. Person类是Student类的基类.
继承是有单根性,也就是一个类只能继承一个类,但是类也有传递性,当A类继承自B类.B类又继承自C类.那么这个时候A类同时拥有B、C类中的成员
在新添加类模块的时候.有个选项 指定父类的名称。
需要注意的一个问题,可以定义一个父类的指针指向子类对象,但是这个时候这个对象不能调用子类自己定义的方法,并且也不能使用子类自己定义的属性,如果在子类中改写了父类的方法,调用这个方法是调用的是已经改写的那个方法。可以定义一个子类的指针指向父类对象,会报个警告,不会报错,但是这个时候这个对象不能调用子类的方法,并且不能使用子类自己定义的属性,如果在子类中改写了父类的方法,调用这个方法是调用的是在父类中没被改写的那个方法。
3)多态就是在子类中重新父类的方法,比如找三个人过来,这三个人中一个是理发师,第二个是医生,第三个是演员,那么让这三个人执行cut这个操作是,理发师执行的是剪头发,医生执行的是动手术,演员执行的是停止表演。同一个事情表现出多种形态,就是多态。简单的说,多态就是子类重写方法,当父类指针指向子类对象的时候. 调用多个对象的方法,而这些方法是被子类重写了的,那么这个时候,不同的子类对象对于同1个方法是具有完全不同的表现形式.在子类中重写方法不需要重新声明。