0x01 重写方法
在制作全新的子类时,经常会添加自己的方法。
有时会添加一个能够向类中引入特有功能的新方法,有时也会替换或改进某个超类定义的现有方法。
当然也可以选择不添加新特性,而是创建一个子类并通过它重写继承自超类的行为。
比如说我们在Shape类中提供了一个draw方法,但是它的实现内容为空,这样每个子类都能实现各自的功能。当Circle类实现了自己的draw方法时,我们就说它重写了draw方法。 此时向Circle对象发送draw消息,方法调度机制将运行重写后的方法,而超类中的draw方法将被忽略。
@interface Shape : NSObject
{
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor:(ShapeColor)fillColor;
- (void) setBounds:(ShapeRect)bounds;
- (void) draw;
@end // Shape
@implementation Circle
- (void) draw
{
NSLog(@“drawing a circle at (%d %d %d %d) in %@“, bounds.x, bounds.y, bounds.width,
bounds.height, colorName(fillColor));
} // draw
@end // Circle
0x02 super关键字
Objective-C提供了一种方法,让我们既可以重写方法的实现,又可以调用超类中的实现方式。
当需要超类实现自身的功能,同时在之前或之后执行某些额外的工作时,这种机制非常有用。
为了调用继承的方法在父类中的实现,需要使用super作为调用的目标。
假设我们不知道Shape类中的具体代码,那我们就没有办法直接去重写它,所以我们在Circle类中重写setFillColor:方法来解决问题。代码先检查颜色的参数,再决定是否修改颜色。然后使用super通知超类Shape将修改后的颜色存储到实例变量fillColor中。
Circle类的接口部分不用修改,只需在实现部分添加代码:
@implementation Circle
- (void)setFillColor:(ShapeColor)c
{
if (c == kRedColor)
{
c = kGreenColor;
}
[super setFillColor: c];
} // setFillColor
@end // Circle
1、super既不是参数也不是实例变量,而是Objective-C提供的一个功能;
2、当我们向super发送消息时,实际上是请求Objective-C向该类的超类发送消息;
3、如果超类中没有定义该消息,Objective-C会和平常一样继续在继承链的上一级中查找;
4、重写方法时,使用super总是一个明智的选择。在我们不熟悉超类的内部实现细节时,就不知道超类能否提供更多的功能。使用super可以确保获得超类的所有方法实现特性。