今天碰到一个疑问,具体是用在父类遵守某个协议,子类继承父类时,父类也实现了协议的方法,有个疑虑是是否会执行子类的方法呢?答案是不能的。
- 思考:假设主人家养了动物,猫,猫继承动物,遵守一套吃的协议。当主人发出吃的信号时,看看动物和猫是怎么响应的。
// ActionDelegate.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol ActionDelegate <NSObject>
- (void)eat;
@end
// Animal.h
#import <Foundation/Foundation.h>
#import "ActionDelegate.h"
#import "Person.h"
NS_ASSUME_NONNULL_BEGIN
@interface Animal : NSObject<ActionDelegate> //接受协议放置位置1
// 主人
@property (nonatomic, strong) Person *holder;
@end
NS_ASSUME_NONNULL_END
// Animal.m
#import "Animal.h"
@interface Animal() //<ActionDelegate> 接受协议放置位置2
@end
@implementation Animal
- (void)eat {
NSLog(@"Animal eat");
}
- (Person *)holder {
if (!_holder) {
_holder = [[Person alloc] init];
_holder.delegate = self;
}
return _holder;
}
@end
// Cat.h
#import "Animal.h"
NS_ASSUME_NONNULL_BEGIN
@interface Cat : Animal
//- (void)eat; // 此处可不用写也行3
@end
NS_ASSUME_NONNULL_END
//Cat.m
#import "Cat.h"
@implementation Cat
- (void)eat {
NSLog(@"Cat eat");
}
@end
// Person.h
#import <Foundation/Foundation.h>
#import "ActionDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
@property (nonatomic, weak) id<ActionDelegate> delegate;
- (void)CallAnimalEat;
@end
NS_ASSUME_NONNULL_END
// Person.m
#import "Person.h"
@implementation Person
- (void)CallAnimalEat {
if (self.delegate && [self.delegate respondsToSelector:@selector(eat)]) {
[self.delegate eat];
}
}
@end
//ViewController.m
#import "ViewController.h"
#import "Animal.h"
#import "Cat.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Animal *animal = [[Animal alloc] init];
[animal.holder CallAnimalEat];
Cat *cat = [[Cat alloc] init];
[cat.holder CallAnimalEat];
// Do any additional setup after loading the view.
}
@end
执行结果如下:
2020-07-11 16:01:01.987303+0800 Delegate[6978:531839] Animal eat
2020-07-11 16:01:01.987522+0800 Delegate[6978:531839] Cat eat
附:
不论<ActionDelegate>放在接受协议放置位置1还是放在接受协议放置位置2 子类都不需要在.h文件中再对接受协议中的方法声明一次(参看:此处可不用写也行3)
子类实现了协议中的方法就执行子类的方法,不实现执行父类的方法。
网友评论