目录
一,基本概念
二,优缺点
三,高耦合的示例
四,使用要点
五,使用场景
六,Super简单介绍
七,替代方案
八,多继承html
继承、封装、多态是面向对象的三大支柱。OC
只支持单继承,父类能够有多个子类,但子类有且仅有一个父类git
优势:代码复用
缺点:高耦合github
1,父类只给子类提供服务,并不涉及子类的业务逻辑
2,层级关系明显,功能划分清晰,父类和子类互不干扰
3,父类的全部变化都须要在子类中体现,此时耦合已经成为需求
4,不宜超过2层,第3层继承是滥用的开端bash
5,做为一个开发人员,有一个交流学习的圈子是很重要的。如今小编这边有一个学习交流群(810733363)。欢迎你们进入交流学习。学习
1,继承系统类库,好比自定义UITableViewCell
2,把公共的属性和方法放入父类中ui
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
- (void)eat;
@end
// Man
@interface Man : Person
@end
@implementation Man
- (void)eat {
NSLog(@"man eat");
}
@end
// Woman
@interface Woman : Person
@end
@implementation Woman
- (void)eat {
NSLog(@"woman eat");
}
@end
// 使用
Man *man = [Man new];
man.name = @"111";
[man eat];
Woman *woman = [Woman new];
woman.name = @"222";
[woman eat];
复制代码
super
的本质跟runtime
有关,详细的放在runtime
系列中进行讲解atom
1,在子类的init
方法中必须调用[super init]
,由于在初始化子类以前必须先初始化父类spa
- (instancetype)init {
self = [super init];
if (self) {
}
return self;
}
复制代码
2,若是父类的某个方法没有实现,在子类的此方法中不能调用[super method]
,不然会crash3d
@implementation Person
@end
@implementation Man
- (void)eat {
[super eat]; // crash
NSLog(@"man eat");
}
@end
复制代码
3,若是父类的某个方法实现了,在子类的此方法中看状况调用[super method]
,若是须要用到父类的代码就调用,若是不须要就不调用,直接覆盖便可
@implementation Person
- (void)eat {
NSLog(@"person eat");
}
@end
@implementation Man
- (void)eat {
[super eat];
NSLog(@"man eat");
}
@end
复制代码
4,重写系统的方法通常都须要调用[super method]
,由于系统内部作了不少初始化的工做
- (void)viewDidLoad {
[super viewDidLoad];
}
复制代码
5,在子类的某个方法中调用[super method]
,在父类该方法中的self
实际上是子类的对象
@implementation Person
- (NSString *)name {
return @"111";
}
- (void)eat {
NSLog(@"person %@ eat", self.name);
NSLog(@"person: %@", self);
}
@end
@implementation Man
- (NSString *)name {
return @"222";
}
- (void)eat {
[super eat];
NSLog(@"man %@ eat", self.name);
NSLog(@"man: %@", self);
}
@end
// 使用
Man *man = [Man new];
[man eat];
// 打印
person 222 eat // 不是111
person: <Man: 0x6000012f2e90> // 不是Person
man 222 eat
man: <Man: 0x6000012f2e90>
复制代码
若是想达到代码复用而且可以解耦的效果,能够考虑下列几种方案
1,协议:把公共方法放入协议中(一般会放在父类中)
@protocol PersonProtocol <NSObject>
- (void)eat;
@end
// Man
@interface Man : NSObject <PersonProtocol>
@end
@implementation Man
- (void)eat {
NSLog(@"man eat");
}
@end
// Woman
@interface Woman : NSObject <PersonProtocol>
@end
@implementation Woman
- (void)eat {
NSLog(@"woman eat");
}
@end
复制代码
2,代理:自定义公共方法(一般把公共方法放入父类中,再在子类中自定义)
@protocol PersonDelegate <NSObject>
- (void)personStartEat;
@end
// Person
@interface Person : NSObject
@property (nonatomic, weak) id<PersonDelegate> delegate;
- (void)eat;
@end
@implementation Person
- (void)eat {
if ([self.delegate respondsToSelector:@selector(personStartEat)]) {
[self.delegate personStartEat];
}
}
@end
// 使用
@interface ViewController () <PersonDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *person = [Person new];
person.delegate = self;
[person eat];
}
- (void)personStartEat {
NSLog(@"每一个使用Person的类均可以自定义此方法");
}
@end
复制代码
3,组合:看看Casa大神是如何使用的
4,AOP(面向切面编程):把每一个控制器公共的操做抽取出来统一处理(一般会放在BaseViewController
中)
@implementation ViewControllerConfigure
+ (void)load {
[ViewControllerConfigure sharedInstance];
}
+ (instancetype)sharedInstance {
static ViewControllerConfigure *_sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[ViewControllerConfigure alloc] init];
});
return _sharedInstance;
}
- (instancetype)init {
if (self = [super init]) {
// 拦截全部控制器的viewDidLoad方法
[UIViewController aspect_hookSelector:@selector(viewDidLoad)
withOptions:AspectPositionAfter
usingBlock:^(id<AspectInfo> aspectInfo) {
[self viewDidLoad:aspectInfo.instance];
}
error:nil];
}
return self;
}
- (void)viewDidLoad:(UIViewController *)viewController {
NSLog(@"能够在这里统一处理");
}
@end
复制代码
虽然OC
不支持多继承,但能够经过下列几种方案间接的实现
1,协议
@protocol Father <NSObject>
- (void)handsome;
@end
@protocol Mather <NSObject>
- (void)beautiful;
@end
@interface Son : NSObject <Father, Mather>
@end
@implementation Son
- (void)handsome {
NSLog(@"帅气的");
}
- (void)beautiful {
NSLog(@"美丽的");
};
@end
复制代码
2,组合
@interface Father : NSObject
- (void)handsome;
@end
@interface Mather : NSObject
- (void)beautiful;
@end
// Son
@interface Son : NSObject
- (void)handsome;
- (void)beautiful;
@end
@interface Son ()
@property (nonatomic, strong) Father *father;
@property (nonatomic, strong) Mather *mather;
@end
@implementation Son
- (instancetype)init {
self = [super init];
if (self) {
_father = [Father new];
_mather = [Mather new];
}
return self;
}
- (void)handsome {
[_father handsome];
}
- (void)beautiful {
[_mather beautiful];
}
@end
复制代码
3,消息转发
@interface Father : NSObject
- (void)handsome;
@end
@implementation Father
- (void)handsome {
NSLog(@"帅气的");
}
@end
// Mather
@interface Mather : NSObject
- (void)beautiful;
@end
@implementation Mather
- (void)beautiful {
NSLog(@"美丽的");
};
@end
// Son
@interface Son : NSObject
- (void)handsome;
- (void)beautiful;
@end
@interface Son ()
@property (nonatomic, strong) Father *father;
@property (nonatomic, strong) Mather *mather;
@end
@implementation Son
- (instancetype)init {
self = [super init];
if (self) {
_father = [Father new];
_mather = [Mather new];
}
return self;
}
// 告诉系统把消息转发给哪一个对象
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([_father respondsToSelector:aSelector]) {
return _father;
} else if ([_mather respondsToSelector:aSelector]) {
return _mather;
}
return nil;
}
@end
// 使用
Son *son = [Son new];
[son handsome];
[son beautiful];
// 打印
帅气的
美丽的
复制代码
@implementation Son
- (instancetype)init {
self = [super init];
if (self) {
_father = [Father new];
_mather = [Mather new];
}
return self;
}
// 先对方法从新签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (signature == nil) {
if ([_father respondsToSelector:aSelector]) {
signature = [_father methodSignatureForSelector:aSelector];
} else if ([_mather respondsToSelector:aSelector]) {
signature = [_mather methodSignatureForSelector:aSelector];
}
}
return signature;
}
// 再转发消息
- (void)forwardInvocation:(NSInvocation *)anInvocation {
SEL sel = [anInvocation selector];
if ([_father respondsToSelector:sel]) {
[anInvocation invokeWithTarget:_father];
} else if ([_mather respondsToSelector:sel]) {
[anInvocation invokeWithTarget:_mather];
}
}
@end复制代码
来源:本文为第三方转载,若有侵权请联系小编删除。