,继承

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(超类)是否能响应其方法,结果是其父类能够响应该消息。

实例变量

以上是关于,继承的主要内容,如果未能解决你的问题,请参考以下文章

什么是多重继承,单重继承?

python 单继承多继承菱形继承

JSJavaScript继承 - 原型链 - 盗用构造函数 - 组合继承 -原型式继承 - 寄生式继承 - 寄生式组合继承

C++之继承总结(继承的定义与格式,赋值转换,默认成员函数,菱形继承及菱形虚拟继承)

c++继承汇总(单继承多继承虚继承菱形继承)

C++继承汇总(单继承多继承虚继承菱形继承)