Objective-C继承(Inheritance)——语法格式

0x01 为什么要使用继承?

观察上一章用OOP思想写出来Circle和Rectangle的接口:

@interface Circle : NSObject
{
@private
 ShapeColor  fillColor;
 ShapeRect   bounds;
}
- (void) setFillColor:(ShapeColor)fillColor;
- (void) setBounds:(ShapeRect)bounds;
- (void) draw;
@end // Circle

@interface Rectangle : NSObject
{
@private
 ShapeColor fillColor;
 ShapeRect bounds;
}
- (void) setFillColor:(ShapeColor)fillColor;
- (void) setBounds:(ShapeRect)bounds;
- (void) draw;
@end // Rectangle

还有Circle和Rectangle的实现:

@implementation Circle
- (void)setFillColor:(ShapeColor)c
{
 fillColor = c;
} // setFillColor
- (void)setBounds:(ShapeRect)b
{
 bounds = b;
} // setBounds
// ...
@end // Circle

@implementation Rectangle
- (void) setFillColor: (ShapeColor) c
{
fillColor = c; } // setFillColor
- (void)setBounds:(ShapeRect)b
{
 bounds = b;
} // setBounds
// ...
@end // Rectangle


程序中有大量结构相似的代码,其中的接口和实现都显得非常相似,甚至除了名称不同,其他都是相同的。


当编程过程中出现这样的重复内容,就意味着这是一个失败的架构。

维护两倍以上的代码,意味着修改代码时必须修改多处,这样做将提高出错几率。


继承将是一个重要的OOP特性,使得合并相似代码成为可能。

我们可以创建一个全新的Shape类,用于保存Circle类和Rectangle类共有的实例变量和声明方法,Circle类和Rectangle类各自特有的draw方法仍然自己保留。



0x02 继承的语法格式

@interface Circle: NSObject

1、冒号后面的标识符是需要继承的类。在Objective-C中可以选择不继承,但使用了Cocoa框架,就需要继承NSObject类,因为它提供了大量有用的特性;

2、Objective-C不同于C++,前者不支持多继承。


引入继承特性,Circle和Rectangle的接口精简如下:

@interface Circle : Shape
@end // Circle

@interface Rectangle : Shape
@end // Rectangle

现在,我们需要写一个Shape类的接口声明和实现代码,将前面不同类中重复的代码包含到自身中:

@interface Shape : NSObject {
  ShapeColor fillColor;
  ShapeRect bounds;
}
- (void) setFillColor:(ShapeColor)fillColor;
- (void) setBounds:(ShapeRect)bounds;
- (void) draw;
@end // Shape

@implementation Shape
- (void)setFillColor: (ShapeColor)c
{
 fillColor = c;
} // setFillColor
- (void)setBounds: (ShapeRect)b
{
  bounds = b;
} // setBounds
- (void) draw
{
} // draw
@end // Shape

1、draw方法在此没有实现任何功能,因为它将在不同的类中有不同的实现。但我们仍然需要在此定义它,以便Shape的所有子类能够通过它来实现各自的方法;

2、在方法定义中不写任何内容或者返回一个虚值(dummy)都是可以通过编译的。


然后再写Circle类和Rectangle类的实现,他们将变得非常简单:

@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


@implementation Rectangle
- (void)draw
{
 NSLog(@“drawing rect at (%d %d %d %d) in %@“,
      bounds.x, bounds.y,
      bounds.width, bounds.height,
      colorName(fillColor));
} // draw
@end // Rectangle

从始至终,我们都不需要改变main( )函数中的代码,因为我们没有改变对象响应的办法,也没有改变它们的行为。






猜你喜欢

转载自blog.csdn.net/qq_33737036/article/details/80988971
今日推荐