程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> OC教程2繼承與復合

OC教程2繼承與復合

編輯:關於C語言

OC教程2繼承與復合


OC2

本章教程主要討論OC的繼承語法以及類的復合編程模式。

  1. OC繼承語法
  2. OC語言的動態特性
  3. OC的復合模式
  4. super關鍵字

    1,OC繼承語法

    OC語法只支持單根繼承,即一個類只能有一個父類。

    繼承關鍵字為:

    @interface 類目 : 父類名
    

    例如我們昨天聲明的三角形類

    @interface Triangle : NSObject
    
    @end
    

    表示Triangle類是繼承與NSObject類。Triangle是NSObject的子類,NSObject是Triangle的父類。

    OC語法中規定,通過繼承方式,可以繼承父類的所有方法和除私有權限以外的所有成員變量。

    例如上一章的三角形類

    @interface Triangle : NSObject
    
    @property double a;
    @property double b;
    @property double c;
    
    -(instancetype)initWithA:(double)a B:(double)b C:(double)c;
    -(double)area;
    
    @end
    
    @implementation Triangle
    
    - (instancetype)initWithA:(double)a B:(double)b C:(double)c
    {
        self = [super init];
        if (self) {
            self.a = a;
            self.b = b;
            self.c = c;
        }
        return self;
    }
    
    -(double)area
    {
        double s=(_a+_b+_c)/2;
        return sqrt(s*(s-_a)*(s-_b)*(s-_c));
    }
    

    本章我們可以通過繼承的方法創建一個新的三角形類

    @interface TriangleSub : Triangle
    
    @end
    
    @implementation TriangleSub
    
    @end
    

    可以看到我們新創建的TriangleSub類中沒有聲明任何方法也沒有實現任何方法。但是通過繼承語法,我們無償獲得了父類的所有方法和成員變量。

    TriangleSub * subT = [[TriangleSub alloc] initWithA:10 B:11 C:12];
    double s = [subT area];
    NSLog(@"s = %g",s);//NSLog函數是OC中向控制台輸出信息的函數
    

    2,OC語言的動態特性

    OC語言是動態類型語言,其表現為調用方法時,不會依據對象指針類型調用對象方法,而根據對象指針使用的內存類型調用響應的方法。

    下面通過代碼描述這個特性。

    首先我們創建一個測試類TestClass

    @interface TestClass : NSObject
    
    -(void)test;
    
    @end
    
    @implementation TestClass
    
    -(void)test
    {   
        NSLog(@"這裡是TestClass類的test方法");
    }
    @end
    

    我們繼續創建兩個類:

    SubA繼承與TestClass

    @interface SubA : TestClass
    
    
    @end
    
    @implementation SubA
    
    //重寫父類的方法
    -(void)test
    {   
        NSLog(@"這裡是SubA類的test方法");
    }
    @end
    

    SubB繼承與TestClass

    @interface SubB : TestClass
    
    @end
    
    @implementation SubB
    
    //重寫父類的方法
    -(void)test
    {   
        NSLog(@"這裡是SubB類的test方法");
    }
    @end
    

    現在做如下測試

    SubA * a = [[SubB alloc] init];
    [a test];//這樣調用沒有編譯錯誤,復合OC的語法規則,那會輸出哪個結果。
    

    根據我們之前講的,OC的動態特性的表現形式

    對象指針在調用方法是,不會根據對象指針類型調用響應方法,而是根據對象指針指向的內存類型調用響應的方法

    由此可見,對象指針a的類型為SubA類型,但其指向的內存類型為SubB類型。所以用對象指針調用test方法時,會調用SubB的test方法。

    其輸出結果為:這裡是SubB類的test方法。

    由於OC語法動態特性的原因,在編寫代碼的過程中,對象指針類型只在編譯時起作用。在運行過程中沒有任何影響。

    OC語法推出一個id關鍵字,表示在編譯過程中不指定類型。

    使用id類型編寫代碼對運行不會有任何影響。但在IDE環境中,變無法開啟代碼自動補全功能,因IDE工具並不知道該對象指針是什麼類型,所以無法進行代碼自動提示和補全。

    3,OC的復合模式

    在OC的復合模式就是把其他對象作為自身的題部分,以提升自身的功能。

    比如我現在要制作一台電腦,電腦需要CPU,顯示器,鼠標和鍵盤等。這些東西的研發都是很復雜的過程。如果現在有成型的CPU等組件,就可以直接用這些組件攢一台電腦。復合模式就是這樣。

    所有我們在制作電腦前要先找到這些組件。這些組件並不需要我們來制作,有專業的公司提供這些成型的組件。

    在本章練習的SDK中提供了如下組件。

    KeyBoard    鍵盤類
    BigMouse    鼠標類
    Monitor     顯示器類
    IntelCPU    CPU類
    

    下面就用SDK中提供的各種組件來快速制作一台電腦。

    首先我們進行電腦類的聲明。需要使用的組件都聲明成屬性,作為電腦類的一部分。

    @interface Computer : NSObject
    
    @property(strong, nonatomic) KeyBoard * aKeyBoard;
    @property(strong, nonatomic) BigMouse * aMouse;
    @property(strong, nonatomic) Monitor  * aMonitore;
    @property(strong, nonatomic) IntelCPU * aCPU;
    
    @end
    

    在這裡我們先補充一下屬性括號中的內容。

    屬性括號中的內容為屬性控制符,分別對屬性的讀寫權限,內存管理和線程操作做出相關規定。

    1. 讀寫權限由兩個關鍵字控制,分別為:readonlyreadwrite。其中如果不寫默認為readwrite。通常屬性的讀寫權限都為可讀可寫。
    2. 內存管理權限由四個關鍵字控制,分別為:assgin,strong,weakcopy。如果不寫,默認為assgin。如果屬性類型為基本數據類型,那麼只能用assgin。如果屬性類型為對象指針,一般情況下用strong,特殊情況下用weakcopy。特殊情況在後面的內存管理章節會展開講解。
    3. 線程操作權限由兩個關鍵字控制,分別為:atomicnonatomic。其中如果不寫默認為atomic。通常我們使用nonatomic作為線程操作,其具體內容在後續的多線程章節會展開講解。

      然後繼續實現電腦類,因CPU等組件是電腦的一部分,所以我們需要重新電腦的初始化方法,在電腦初始化的的同時也初始化各種組件,為其分配內存。

      @implementation Computer
      
      - (instancetype)init
      {
          self = [super init];
          if (self) 
          {
              self.aKeyBoard = [[KeyBoard alloc] init];
              self.aMouse = [[BigMouse alloc] init];
              self.aMonitore = [[Monitor alloc] init];
              self.aCPU = [[IntelCPU alloc] init];
          }
          return self;
      }
      
      @end
      

      經過聲明組件屬性,為組件的對象指針分配內存。我們就使用成型的組件快速的制作好了一個功能完整的電腦。

      4,super關鍵字

      通常繼承和復合會一同使用,來快速構造一個復雜的對象。

      例如現在有一個需求,要求我們快速制作一個可以除甲醛的高級空調。通常我們並不是從零開始研發,而是基於一定基礎開始制作。

      在這裡,我提供了兩個對象作為研發的基礎

      1. Kongtiao類,具有制冷方法
      2. ChuJiaquan類,具有除甲醛的方法

        以下是Kongtiao類的聲明

        @interface Kongtiao : NSObject
        
        -(void)zhiling;
        
        @end
        

        以下是ChuJiaquan類的聲明

        @interface ChuJiaQuan : NSObject
        
        -(void)chuJQ;
        
        @end
        

        首先明確我們制作的是一個空調,所有我們創建一個高級空調類繼承與空調類。

        然後高級空調需要有除甲醛的功能,我們通過復合模式,把除甲醛的模塊作為高級的空調的一部分。

        最後我們重寫父類的制冷方法,在制冷過程中添加除甲醛的步驟。但是在重寫的方法會覆蓋掉父類原有的方法。這裡我們需要在重寫方法中手動調用父類原始方法。就需要用到super關鍵字。

        @interface NewKongtiao : Kongtiao
        
        @property(strong, nonatomic) ChuJiaQuan * cJQ;
        
        @end
        
        @implementation NewKongtiao
        
        - (instancetype)init
        {
            self = [super init];
            if (self) 
            {
                self.cJQ = [[ChuJiaQuan alloc] init];
            }
            return self;
        }
        -(void)zhileng
        {
            [super zhileng];
            [self.cJQ chuJQ];
        }
        
        @end
        

        這樣我們在使用高級空調制冷的同時,也同時能夠除甲醛了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved