,继承
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了,继承相关的知识,希望对你有一定的参考价值。
Objective-C 基础教程第四章,继承
//------------------------------------------------------------------------------
//OC 面向对象继承代码演示 ,矩形 圆形继承于Shape类
//
//《OC基础教程》 第四章第二小节
//------------------------------------------------------------------------------
#import <Foundation/Foundation.h>
//----------------------------------------变量声明--------------------------------
//几何体形状类型
typedef enum
kCircle, //圆圈
kRectangle,//矩形
kEgg, //鸡蛋
ShapeType;
//几何体颜色类型
typedef enum
kRedColor, //红色
kGreenColor,//绿色
kBlueColor, //蓝色
ShapeColor;
//几何体轮廓结构体
typedef struct
int x,y,width,height;
ShapeRect;
//-------------------------------------------------------------------------------
NSString *colorName(ShapeColor color)
switch (color)
case kRedColor:
return @"red";
break;
case kGreenColor:
return @"green";
break;
case kBlueColor:
return @"blue";
break;
return @"no clue";
//================几何体类====================
/*几何体接口*/
@interface Shape : NSObject
ShapeColor fillColor;
ShapeRect bounds;
- (void) setFillColor:(ShapeColor)fillColor;
- (void) setBounds:(ShapeRect)bounds;
- (void) draw;
@end
/*几何体实现*/
@implementation Shape
- (void) setFillColor:(ShapeColor)fillColor
self->fillColor = fillColor;
- (void) setBounds:(ShapeRect)bounds
self->bounds = bounds;
-(void) draw
@end
//================圆型类====================
/*圆型类接口,继承自Shape*/
@interface Circle : Shape
@end
/*圆型类实现,重写父类draw函数*/
@implementation Circle
- (void) draw
NSLog(@"drawing a circle at (%d %d %d %d) in %@",
bounds.x,bounds.y,
bounds.width,bounds.height,
colorName(fillColor));
@end
//================矩形类====================
/*矩形类接口,继承自Shape*/
@interface Rectangle : Shape
@end
/*矩形类实现,重写父类draw函数*/
@implementation Rectangle
- (void) draw
NSLog(@"drawing a rectangle at (%d %d %d %d) in %@",
bounds.x,bounds.y,//这里有个疑问,Rectangle类是如何能访问到bounds这变量的?
bounds.width,bounds.height,//具体看本章的实例变量小节。
colorName(fillColor));
@end
//===========================================
int main(int argc, const char * argv[])
@autoreleasepool
id shapes[2];
ShapeRect rect0 = 0, 0, 10, 30 ;
shapes[0] = [Circle new];
[shapes[0] setBounds: rect0];
[shapes[0] setFillColor: kRedColor];
[shapes[0] draw];
ShapeRect rect1 = 30, 40, 50, 60 ;
shapes[1] = [Rectangle new];
[shapes[1] setBounds: rect1];
[shapes[1] setFillColor: kBlueColor];
[shapes[1] draw];
return 0;
继承的语法格式
和C++有点类似,OC继承的语法格式如下:
//圆形类接口声明 (圆形类继承自Shape 几何体类)
@interface Circle:Shape
@end
只不过需要注意的是OC中的继承无法用:进行多继承
,比如如下的语法就是错误的。
//这样会导致编译错误
@interface Circle:Shape:NSObject
@end
你可以通过Object-C的其他特性来达到多继承的效果,例如类别(category)
,后续第12章节将会学习到和协议(protocol)
第13章节。
继承的工作机制
在如上代码中,我们对比第三章的代码进行了比较大的调整,提取了Circle和Rectangle的重复代码并将其加入Shape类中。
绝妙的是程序的其他部分不需要修改依然可以正常运行。
在此你会发OOP的一个强大地方:你可以对一个程序做一些重大的改变,如果你非常仔细,改变后程序仍然能正常运行。也就是重构
。
方法调度
当执行[shape setFillColor:RedColor];
代码的时候,OC
的方法调度机制
首先会寻找接收消息的对象,在当前例子中的对象是shape
他是Circle
类的对象,该对象拥有一个当前类的this指针,在OC中他是self
指针。通过该指针来寻找他执行的代码,比如我们调用这句代码的时候self
指针就会找到setFillColor
这代码。
那么当我们有继承属性的时候,可以从如下图中看到shape
对象还有一个指向其SuperClass(超类)
的指针。
当我们指向[shape setFillColor:RedColor];
代码的时候,调度程序先询问Circle
类是否能响应setFillColor:
消息,看如下图Circle Class没有声明定义setFillColor
方法,所以调度程序会继续询问其SuperClass(超类)
是否能响应其方法,结果是其父类能够响应该消息。
实例变量
以上是关于,继承的主要内容,如果未能解决你的问题,请参考以下文章
JSJavaScript继承 - 原型链 - 盗用构造函数 - 组合继承 -原型式继承 - 寄生式继承 - 寄生式组合继承