对于私有属性和方法,子类和父类同名基本上没有什么影响.但是有几点需要注意一下:
如果是属性同名,子类和父类会拥有各自独立的实例变量。
如果是方法同名,按照消息发送的过程,执行的自然是子类中的方法。
举个栗子:
父类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @interface Animal : NSObject
@property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger age;
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
- (void)hello;
@end
@interface Animal ()
@property (nonatomic, copy) NSString *hobbit;
@end
@implementation Animal
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age { self = [super init]; if (self) { _name = name; _age = age; } return self; }
- (void)hello { NSLog(@"父类方法,%@ %ld %@", _name, (long)_age, self.hobbit); }
- (void)run { NSLog(@"父类方法run"); }
- (NSString *)hobbit { if (_hobbit == nil) { _hobbit = @"unknown"; } return _hobbit; }
@end
|
子类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @interface Person : Animal
@end
@interface Person ()
@property (nonatomic, copy) NSString *hobbit;
@end
@implementation Person
- (void)hello { [super hello]; NSLog(@"子类方法,%@ %ld %@", self.name, (long)self.age, self.hobbit); [self performSelector:@selector(run)]; }
@end
|
属性同名,拥有各自独立的实例变量:
方法同名:
下面代码会打印什么?
1 2 3 4 5
| Person *p = ; ;
Animal *ani = ; ;
|
打印:
1 2 3 4
| 2020-03-23 10:17:13.648428+0800 父子类属性同名[47652:6589153] 父类方法,mattt 3 (null) 2020-03-23 10:17:13.648780+0800 父子类属性同名[47652:6589153] 子类方法,mattt 3 (null) 2020-03-23 10:17:13.648815+0800 父子类属性同名[47652:6589153] 父类方法run 2020-03-23 10:17:13.648853+0800 父子类属性同名[47652:6589153] 父类方法,sun 3 unknown
|
可以看到父类的hobbit属性是实现了懒加载的,但子类执行到父类hello方法里的self.hobbit时并没有执行懒加载代码,打印依然为null。这是因为执行self.hobbit时,执行的是子类自己的getter/setter方法。
之所以写这个,是因为在重构的时候发现上面的懒加载代码怎么死活都不执行。