天天看點

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、關于方法的覆寫:

   覆寫的方法是一個同名的新方法,必須有相同的傳回類型,并且參數的數目也不能改變。