Objective-C之成魔之路【10-继承性】

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

师宗网站制作公司哪家好,找创新互联建站!从网页设计、网站建设、微信开发、APP开发、响应式网站建设等网站项目制作,到程序开发,运营维护。创新互联建站成立于2013年到现在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)希望通过覆写一个或多个方法来改变类的默认行为。


抽象类:

有时,创建类只是为了更容易创建子类。

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

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


注意:

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

下面再通过一个矩形类和正方形类的实例说明方法重写问题:
Rectangle.h文件:
#import   @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  #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

当前文章:Objective-C之成魔之路【10-继承性】
文章源于:http://myzitong.com/article/pdccde.html