OC基础5:继承

1、根类即是最顶层的类,父类也可称为超类;

 

2、关于实例变量的继承:

   只有声明在@interface部分的实例变量才能被子类继承:包括在类名后马上使用花括号声明的变量和使用@property声明的变量,都可以继承。如果完全声明在@implementation部分的变量,则属于私有变量,需要提供方法才能访问。

 

3、每个实例都有自己的一套实例变量,即使这套实例变量是继承来的。比如bClass是从aClass继承来的,他们都有一个变量(int) n,那么当改变了aClass.a的值的时候,bClass.a的值不会随着改变。他们是两个不同的实例。

   反观另一种特别的情况(代码8-5):Rectangle类是矩形类,XYPoint类是点类,Rectangle类里面包含了一个变量origin是(XYPoint *)类型的,用来存放这个矩形的位置点。新建了一个Rectangle类的实例myRect,新建了一个XYPoint类的实例myPoint,然后通过语句

   myRect.origin= myPoint;

   将myPoint的值赋给myRect作为它的位置点。这时候出现了一种情况,当myPoint的值改变了以后,myRect所包含的origin变量的值也跟着改变了。原因是使用上面的语句的时候,赋给origin变量的值并不是myPoint的内容,而是一个指针,指向了myPoint的存储位置,所以当myPoint的内容改变了以后,origin变量的值也跟着改变了,myRect并没有自己新建一套变量去存储myPoint的内容,存放的仅仅是一个指针。

   对于这两种情况要区别去理解:aClass和bClass是两个不同的实例,各有各的变量;myRect并没有用一个变量去存储myPoint的内容,仅仅只用了一个(XYPoint *)类型的变量来存放了myPoint的指针。

 

4、对于3中的myRect和myPoint,只要在myRect里面重新声明了myPoint用以存放位置的几个变量,然后把myPoint里面对应的变量值一一赋给自己的变量,那么myPoint的值再怎么改变也不会再影响到myRect包含的位置点变量了。其实即是在myRect的内部声明一个myPoint,即有了一个私有的myPoint。

 

5、关于@class指令,比如在接口文件CClass.h中有如下代码段:

  #import <Foundation/Foundation.h>

   @class AClass

   @interfaceCClass: NSObject

   …

   在这段代码中出现了指令@class,它的意思是接下来的代码中会使用到AClass这个类,这里告诉编译器接下来如果遇到“AClass”就把它当做一个类来对待即可。

   但是如果下方代码要访问到Aclass包含的变量,那就会报错,这种情况应该把Aclass.h这个接口文件import进来。

 

6、关于4,其实不用再去声明XYPoint类的变量,只需要将Rectangle类中设置origin的方法改写如下即可:

   -(void)setOrigin: (XYPoint *) pt {

    if (! origin) {   //如果origin是空的,则为false,那么(! origin)为true,执行以下代码;

      origin = [[XYPoint alloc] init];

    }

    origin.x = pt.x;  //x和y都是XYPoint的变量,这里origin是一个(XYPoint *)型的变量,

    origin.y = pt.y;  //它也会包含有一套xy,所以不需再去声明一套;

   }

   直接在方法中设置一套xy,就不会受myPoint影响。

   这种情况下,虽然origin.x被赋予的仍然是pt.x的指针,但是也完全不需要担心会受到myPoint的影响的了,因为虽然现在origin.x和pt.x指向的是同一块内存,但是如果改变了pt.x的值的话,其实系统是新分配了一块内存写了一个新的值,然后让pt.x指向这块新的内存,origin.x指向的内存不会受到任何影响。

以下图为例:

(1)、origin = myPoint是这种情况:

OC基础5:继承

(2)、origin.x = pt.x是这种情况:

OC基础5:继承

 

7、在默认的情况下,合成(synthesize)的设值方法只是简单地复制对象的指针,而不是对象的本身,其实即是assign。

 

8、关于方法的覆写:

   覆写的方法是一个同名的新方法,必须有相同的返回类型,并且参数的数目也不能改变。

  

你可能感兴趣的:(继承)