一、继承
继承是指一个新类拥有被继承类(父类)的全部属性和方法。
特点:
1、代码重用,子类可以重写父类的方法,并用super来调用父类的方法
2、类方法可以和对象方法重名(+表示类方法,-表示对象方法)
3、子类中不能定义与父类中同名的成员变量。
4、OC是单继承,一个类只能继承一个直接父类。OC是多层继承,B类继承A类,C类继承B类…
5、父类的改变影响所有的子类,所以子类和父类的耦合度很高。
二、分类(类别):UIButon(Add)
拓展已有类的功能。(Category)
特点
1、为原有的类增加类方法
2、原则上讲,分类是不能增加成员变量的,因为分类的结构体指针中,没有属性列表,只有方法列表。但是可以通过runtime解决无setter/getter的问题。
3、如果在分类中用@property增加成员变量,只能生产getter和setter方法的声明,需要实现get、set方法才能被调用
4、可以访问原有类@protect和@public形的成员变量
5、分类可以扩充系统自带的类的功能。如UIButton之类的
6、不能在分类中定义与原有类同名方法,如果定义了,那么分类中的方法会覆盖原有类的方法(即使不引用)。
7、不同的分类之间也不可以有同名的方法,如果定义了,执行最后编译的方法。
8、需要使用#import引用分类。
三、类扩展:UIButon()
在.m文件中为类增加私有的成员变量和方法。(extension)
特点
1、类扩展不仅可以增加方法,还可以增加实例变量(或者属性)。增加的属性和方法,都是私有的。
2、类拓展只有.h方法,没有.m方法。不能像类别那样拥有独立的实现部分(@implementation部分),也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现。
3、类扩展中声明的方法没被实现,编译器会报警,但是类别中的方法没被实现编译器是不会有任何警告的。这是因为类扩展是在编译阶段被添加到类中,而类别是在运行时添加到类中。
栗子:分类不能增加成员变量,但是使用runtime可以实现
@interface UIButton (Add)
@property(nonatomic,copy) NSString *name;
@end
#import "UIButton+Add.h"
#import <objc/runtime.h>
@implementation UIButton (Add)
static NSString *nameKey = @"nameKey";
- (void)setName:(NSString *)name
{
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY);
}
- (NSString *)name
{
return objc_getAssociatedObject(self, &nameKey);
}
@end