zoukankan      html  css  js  c++  java
  • Objective-C之成魔之路【10-继承性】

    郝萌主倾心贡献。尊重作者的劳动成果。请勿转载。

    假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主。捐赠数额任意。重在心意^_^ 

    我要捐赠: 点击捐赠

    Cocos2d-X源代码下载:点我传送


    继承性是面向对象的重要概念之中的一个。 子类可以继承父类的某些方法和成员变量。 
    作用域限定符为private的成员变量是不能够被继承的。

     

    子类还能够重写父类的方法。

     


    当然,这一切要从根类開始:

    没有父类的类,位于类层次结构的最顶层,称为根(Root)类。

    NSObject是层次结构的最顶端(也就是它上面没有不论什么类),因此称为根类。

    假设使用术语。能够将类称为子类和父类。相同,也能够将类称为子类和超类。

    须要注意的是,要在子类中直接使用实例变量,必须先在接口部分声明。

    在实现部分声明和合成(synthesize)的实例变量是私有的。子类中并不可以直接訪问。

    须要明白定义或合成取值方法。才干訪问实例变量的值。


    继承的概念作用于整个继承链。

    一定要理解下面事实:类的每一个实例都拥有自己的实例变量。即使这些实例变量是继承来的。


    找出正确的方法:

    首先,检查该对象所属的类,以查看在该类中是否明白定义了一个具有指定名称的方法。

    假设有,就使用这种方法。假设未定义,就检查它的父类。

    假设父类中有定义,就使用这种方法,否者。继续找寻。

    直到找到根类也没有发现不论什么方法。


    通过继承来扩展:加入新方法

    继承通经常使用于扩展一个类。


    @class指令:

    @class XYPoint;

    #import "XYPoint.h"


    使用@class指令提高了效率。由于编译器不须要引入和处理整个XYPoint.h文件(尽管它非常小)。

    仅仅须要知道XYPoint是一个类名。

    假设须要引用XYPoint类的方法(在实现部分中),@class指令是不够的,由于编译器须要很多其它的消息。

    说的通俗点:仅仅引用了类就用@class不然就用#import。

    在默认情况下。合成的设值方法仅仅是简单地复制对象指针,而不是对象本身。

    你能够合成还有一种设值方法,而不是制作对象的副本。


    为了了解继承性, 我们看看这种一个场景: 
    一位刚学习面向对象的小菜,自从当上了班长。他就有的忙了。由于录入档案。须要描写叙述和处理个人信息。
    于是他定义了类Person:
    @interface Person: NSObject {
    NSString* name;
    int age;
    NSDate birthDate;
    }
    -(NSString*) getInfo;
    @end

    新的校花School Beauty类:
    一周以后。 小菜又遇到了新的需求。 他的几个表妹非要把各自学校的校花介绍给我他,烦恼呀!

    须要描写叙述和处理校花信息, 于是他又定义了一个新的类Beauty。

     

    @interface Beauty: NSObject {
    NSString* name;
    int age;
    NSDate birthDate;
    NSString* school;
    }
    -(NSString*) getInfo;
    @end


    小结
    Beauty和Person两个类的结构太接近了, 
    者仅仅比前者多出一个属性school 。 却要反复定义其他全部的内容。

    Objective-C提供了解决类似问题的机制, 那就是类的继承。 
    @interface 
    Beauty: Person {
    NSString* school;
    }

    方法重写或者说是覆写方法:

    不能通过继承删除或降低方法。但能够利用覆写来更改继承方法的定义。

    新方法必须具有同样的返回类型,而且參数的数目与覆写的方法同样。

    假设在不同的类中有名称同样的方法,则依据作为消息的接收者的类选择正确的方法。


    为什么要创建子类?

    有例如以下3个理由:

    1)希望继承一个类的方法,或许增加一些新的方法和或实例变量。

    2)希望创建一个类的特别的版本号。

    3)希望通过覆写一个或多个方法来改变类的默认行为。


    抽象类:

    有时,创建类仅仅是为了更easy创建子类。

    因此,这些类名为抽象(abstract)类,或等价地称为抽象超类(abstract superclasses)。

    在该类中定义方法和实例变量,但不期望不论什么人从该类创建实例。


    注意:

    子类不能继承父类中作用域限定符为@private的成员变量。 
    子类能够重写父类的方法,及命名与父类同名的成员变量。 

    以下再通过一个矩形类和正方形类的实例说明方法重写问题:
    Rectangle.h文件:
    #import <Foundation/NSObject.h>
    
    @interface Rectangle: NSObject {
        int width;
        int height;
    }
    
    -(Rectangle*) initWithWidth: (int) w height: (int) h;
    -(void) setWidth: (int) w;
    -(void) setHeight: (int) h;
    -(void) setWidth: (int) w height: (int) h;
    -(int) width;
    -(int) height;
    -(void) print;
    @end
    
    Rectangle.m文件:
    #import "Rectangle.h"
    
    @implementation Rectangle
    
    -(Rectangle*) initWithWidth: (int) w height: (int) h {
        self = [super init];
    
        if ( self ) {
            [self setWidth: w height: h];
        }
    
        return self;
    }
    
    -(void) setWidth: (int) w {
        width = w;
    }
    
    -(void) setHeight: (int) h {
        height = h;
    }
    
    -(void) setWidth: (int) w height: (int) h {
        width = w;
        height = h;
    }
    
    -(int) width {
        return width;
    }
    
    -(int) height {
        return  height;
    }
    
    -(void) print {
        NSLog(@"width = %i, height = %i", width, height );
    }
    @end
    
    Square.h文件:
    #import "Rectangle.h"
    
    @interface Square: Rectangle
    -(Square*) initWithSize: (int) s;
    -(void) setSize: (int) s;
    -(int) size;
    @end
    
    Square.m文件:
    #import "Square.h"
    
    @implementation Square
    -(Square*) initWithSize: (int) s {
        self = [super init];
    
        if ( self ) {
            [self setSize: s];
        }
    
        return self;
    }
    
    -(void) setSize: (int) s {
        width = s;
        height = s;
    }
    
    -(int) size {
        return width;
    }
    
    -(void) setWidth: (int) w {
        [self setSize: w];
    }
    
    -(void) setHeight: (int) h {
        [self setSize: h];
    }
    @end
    
    调试用的main函数:
    #import <Foundation/Foundation.h>
    #import "Square.h"
    #import "Rectangle.h"
    
    int main (int argc, const char * argv[]) {
    
    		Rectangle *rec = [[Rectangle alloc] initWithWidth: 10 height: 20];
        Square *sq = [[Square alloc] initWithSize: 15];
    
        NSLog(@"Rectangle: " );
        [rec print];
    	
    		NSLog(@"Square: " );
        [sq print];
    	
        [sq setWidth: 20];
        NSLog(@"Square after change: " );
        [sq print];
    
        [rec release];
        [sq release];
    		
        return 0;
    }
    
    执行结果:
    Rectangle:
    width = 10, height = 20
    Square:
    width = 15, height = 15
    Square after change:
    width = 20, height = 20
  • 相关阅读:
    【Algorithm】基数排序
    【Algorithm】堆排序
    【Algorithm】快速排序
    【Algorithm】自顶向下的归并排序
    【Algorithm】自底向上的归并排序
    【Algorithm】插入排序
    【Algorithm】选择排序
    java的几个format
    java restful接口
    java解析EXCEL
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6853318.html
Copyright © 2011-2022 走看看