iOS開發入門 ☞ OC語言·筆記六

来源:http://www.cnblogs.com/bossren/archive/2017/02/22/6428475.html
-Advertisement-
Play Games

面向對象的三大特性: 封裝, 繼承, 多態 1. 封裝 1.1 基本概念 將零散的東西組合起來。 廣義上封裝指:將代碼封裝成函數,將實例變數和方法封裝成類,將類封裝成框架.... 面向對象中的封裝指:封裝屬性和方法放在一個對象中,只給外界公開訪問的介面,而且把具體實現隱藏起來。 1.2 封裝的好處 ...


面向對象的三大特性: 封裝, 繼承, 多態

1. 封裝

1.1 基本概念

將零散的東西組合起來。

  • 廣義上封裝指:將代碼封裝成函數,將實例變數和方法封裝成類,將類封裝成框架....
  • 面向對象中的封裝指:封裝屬性和方法放在一個對象中,只給外界公開訪問的介面,而且把具體實現隱藏起來。

1.2 封裝的好處

提高可讀性,可維護性,可擴展性

1.3 OC中的封裝

OC語言天然就是封裝好的。

定義一個類時,@interface部分就是給外界公開的訪問介面。@implementation部分就是隱藏起來的具體實現。

.h文件中寫的是公開的介面

.m文件中寫的是隱藏的實現

//私有方法,只要不在頭文件的介面部分聲明的方法就是私有方法

2. 繼承

2.1 概念

繼承是一種代碼復用技術(代碼重覆使用)。是類與類之間的一種關係(“is a”關係)

B類繼承了A類。A類叫B類的父類,B類叫A類的子類。

其他語言中還有基類,派生類的概念

2.2 繼承的方式

    單繼承  OC, Java...., Swift    單繼承指一個類只能有一個父類.

    多繼承  C++支持多繼承      多繼承指一個類可以有多個父類.

    OC語言中的類在一顆樹上,只有一個祖宗NSObject; swift不只有一顆樹,是一片森林。

2.3 OC中繼承的語法

@interface 類名 : 父類名

 

@end

2.4 什麼情況下用繼承

理論上:

      如果兩個類之間擁有is a關係,這兩個類應該是繼承關係

  狗是動物  Dog is a Animal.

        Animal是父類, Dog是子類

      如果兩個類之間擁有has a關係,應該用組合或聚合

  計算中有一個CPU  Computer has a CPU

  組合和聚合是另一種類與類之間的關係

實際開發中使用繼承:

先寫的父類,還是先寫的子類?//都可以

 

2.5 抽象類

C++: 純虛函數,沒有函數體的函數。存在純虛函數的類是抽象類,不可以實例化了對象。

Java: 抽象方法和抽象類, abstract來聲明

OC OC語言中沒有抽象類和抽象方法的語法。

派生:在子類中添加新的屬性和方法

2.6 重寫:子類對父類的方法不滿意時,可重寫父類中的方法

           隱藏:當子類重寫父類的方法後,子類中將有兩個同名的方法,而從父類中繼承的方法不能在類外被調用

2.6.1 概念

1) override 重寫(覆蓋): 子類不滿意從父類中繼承來的方法,重新將此方法實現了。

要求:方法名和父類一樣,參數類型一樣,返回值一樣。只有方法的實現不一樣。

2) overload 重載: OC中並不存在overload

overload的概念是在一個範圍內(比如一個類中),出現多個方法名相同的方法,這些方法的參數類型不同,導致可以同時出現,我們說,這些方法之間形成了重載的關係。

OC中不允許同一個範圍存在多個方法名相同的方法。

-(id)initWithName:(NSString *)name andAge:(NSUInteger)age;

-(id)initWithName:(NSString *)name andGender:(BOOL)gender; //OC中方法名不同

OC中只有重寫,沒有重載

方法的重寫:子類對父類繼承的方法不滿意,可以在子類中重寫父類的方法。

如果重寫父類的方法,優先調用子類的方法,如果子類沒有重寫父類的方法,則調用父類的方法。

 

2.6.2 註意

雖然父類中的屬性是公開的,但生成的實例變數卻是私有的,在子類中不能訪問

2.6.3 普通方法的重寫

如同perimeter, area, show

方法名相同,參數類型相同,返回值相同

2.6.4 屬性的重寫

如同TRSqaure中的width,height屬性

2.6.5 特殊方法的繼承和重寫

1) 初始化方法

OC中初始化方法是會被繼承的。

繼承來的初始化方法有些可以用,有些不能用。

如果在子類中,繼承自父類的初始化方法不能用(不能完成要求的初始化任務),在子類中就需要重寫這個初始化方法。

2) 類方法(工廠方法)

類方法也可以被繼承

工廠方法自然也可以被繼承,但直接繼承的工廠方法名不匹配,實際開發中很少這樣用。子類最好提供自己的工廠方法。

2.7 繼承的缺陷

  1) 提高了程式的複雜度,維護性和擴展性降低。 

  2) 破壞類的封裝性  慎用繼承!

2.8 為什麼使用繼承?

  1) 代碼復用 

    將子類重覆的代碼抽象到父類中

  2) 制定規範(規則)

    NSObject  

  3) 為了多態

    沒有繼承,就沒有多態

組合與聚合

  類與類之間的一種關係,比較常見;主要作用:代碼復用!

1.1 什麼是組合

  表示兩個對象之間是整體和部分的強關係,是“contains(包含) a”關係,要求兩個類同生共死。

生命周期完全一致,同生共死。部分的生命周期不能超越整體!

例如:一個視窗內有按鈕、標簽,當視窗關閉時,視窗與按鈕、標簽同時銷毀。

 

1.2 組合的定義:

@interface BRButton : NSObject

@end

@interface BREdit : NSObject

@end

@interface BRWindow : NSObject

/**

 *  組合是兩個類的強關係(要求定義成成員變數)

 *  1.在對象初始化時給實例變數賦值(同生共死)

 *  2.不能在類的外部對實例變數訪問/賦值

 */

{

    BRButton *button;

    BREdit *edit;

}

@end

 

  組合Demo:

    

    

1.3 組合的優缺點:

優點:

1)當前對象只能通過所包含的那個對象去調用其方法,所以所包含的對象的內部細節對當前對象是不可見的。

2)當前對象與包含的對象是一個低耦合關係,如果修改包含對象的類中代碼,不需要修改當前對象類的代碼。

3)當前對象可以在運行時動態的綁定所包含的對象。可以通過set方法給所包含對象賦值。

缺點:

容易產生過多的對象

為了能組合多個對象,必須仔細對介面進行定義。

 

1.4 什麼是聚合

表示兩個對象之間是整體和部分的弱關係,是”has a”關係,不要求兩個類同生共死。

生命周期不一致,一個類無法控制另一個類的生死。部分的生命周期可以超越整體。

例如:電腦和滑鼠,電腦被銷毀時,滑鼠可以留下在其他電腦上繼續使用。

1.5 聚合的定義

@interface BRMouse : NSObject

@end

@interface BRComputer : NSObject

//聚合是兩個類的弱關係,在類的外部給實例變數賦值(要求定義成屬性)

@property BRMouse *mouse;

@end

 

  聚合Demo

    

1.6 聚合的優缺點:

優點:

1)被包含的對象通過包含它們的類來訪問

2)很好的封裝

3)被包含的對象內部細節不可見

4)可以在運行時動態定義聚合的方式

缺點:

1)系統可能會包含太多對象

2)當使用不同的對象時,必須小心定義的介面。

組合和聚合的生命周期不一樣,組合是同生共死(關係緊密);聚合沒有特別的關係。

 

1.7  類與類之間常見的三種關係:繼承、組合、聚合

  1) 繼承(繼承的主要目的:代碼復用,制定規範,為了多態)  慎用繼承!(is a關係才用繼承,否則濫用繼承)

  2) 組合和聚合(單純的為了代碼復用)

          組合和聚合的主要目的:是為了代碼的復用。

   

應用場景:(代碼的重覆使用。如果想使用別人的代碼,組合、聚合在一起就可以了)

實際開發中,如果為了復用代碼,提倡使用組合或聚合來複用,而不用繼承。即是把一個類作為另一個類的屬性。(整體與部分)

 

一個類想使用另一個類的方法?怎麼實現...

1.繼承:我繼承你,我就可以直接調你的方法(提高程式的複雜度…不建議用!

2.組合/聚合:把你變成我的一部分(即你是我的屬性),我可以通過訪問你去調用你的方法![.你 你的方法];

 

組合:關係很緊密,同生共死。(cpu焊在主板上,主板壞了cpu也就壞了;綁在一起同生共死!)

聚合:關係很疏遠,不同生共死。(電腦是電腦,cpucpu;這個cpu可以用給這個電腦,也可以用給那個電腦,cpu可以從主板上拔下來給另一個電腦用)

3. 多態(Polymorphism)

3.1 什麼是多態

多種形態,引用的多種形態。對於一個引用變數,可以指向任何類的對象 (一個對外介面,多個內在實現)

 

    父類的引用指向本類或任何子類的對象,會調用不同的方法(表現出多種形態,這種表現叫多態)

TRAnimal *animal = [[TRDog alloc]init];//父類的引用指向子類的對象

[animal eat];//狗啃骨頭 (調用子類重寫的方法)

animal = [[TRCat alloc]init];

[animal eat];//貓吃魚

   多態的表現:同一個引用變數s,調用相同的方法(show),顯示不同的結果。

TRShape *s=[[TRRect alloc]init]; //父類的引用指向子類的對象

[s show]; //顯示矩形  調用子類重寫的方法

s=[TRCircle alloc]init];

[s show]; //顯示圓形

 

3.2 編譯期類型和運行期類型

編譯器編譯時,引用的類型叫編譯期類型。

程式運行時,引用指向的類型叫運行期類型。

       

  程式編譯時按編譯期類型找方法編譯,程式運行時按運行期類型找方法調用。

  父類的引用指向子類的對象時,只能調用父類中有的方法。

  因為編譯器在編譯時是按父類來檢查的,雖然運行時調用的是子類的方法,但是編譯時是按父類來檢查的。

3.3 為什麼用多態

為什麼用父類的引用指向子類的對象:

為了寫出更加能用(通用),相容性更好的代碼。

 

3.4 多態的各種表現【用途】

1)【參數多態】經常在方法的參數表現多態:參數類型使用父類型,可以傳任何子類的對象

NSObject *id類型做為方法的參數區別在於:

NSObject *類型的引用只能調用NSObject類中有的方法。

id類型的引用可以調用任何存在(不能瞎寫)的方法。

(一般不用NSObject *類型,用id類型替代。id有風險的,編譯器根本不檢查對錯)

/** 方法的參數 表現多態 */

void showAnimal(TRAnimal *animal) {

    [animal eat];

    [animal sleep];

    //[animal watchHome];//父類中沒有這個方法編譯不通過

}

int main() {

    @autoreleasepool {

        TRDog *dog = [[TRDog alloc]init];

        showAnimal(dog);

        showAnimal([TRCat new]);

    }

    return 0;

}

 

  2)【返回值多態】方法的返回值上表現多態

    

3)【數組多態】在數組和集合中表現的多態

//數組 表現多態 [多個對象同時執行eat方法]

TRAnimal *animals[3] = {[TRAnimal new], [TRDog new], [TRCat new]};

for (int i = 0; i < 3; i++) {

[animals[i] eat];

}

  

 多態無處不在!

 

 

多態Demo

  

    

    

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引言:Xcode8 之後引用Automatic manage signing 。對於開發者而言,在證書上栽的坑肯定不少。 準備:1.開發者賬號是必須的吧。 2. Xcode設置account (不給Xcode說你的賬號,怎麼找你的證書和app信息) 3.開發者賬號,如圖依次次設置,具體設置內容簡單說 ...
  • 問題:上傳頭像成功後,頭像的url沒變,載入頭像時還是從緩存中根據url載入以前的圖片。 這個問題,很多人遇到過。也受到很多同行的啟發。 圖片url不變,感覺不是很合理,這樣會把緩存搞亂。 但是,作為程式員,我還是得好好想想改怎麼解決這個問題。 1.既然是緩存引起的問題,那我首先考慮的是清除緩存。 ...
  • 代理設計模式 Demo 一、讓別人幫我做事 —— 基本版 二、讓別人幫我做事 —— 引入協議 三、讓別人幫我做事 —— 規範完整版 ...
  • 由OpenDigg 出品的安卓開源項目周報第九期來啦。我們的安卓開源周報集合了OpenDigg一周來新收錄的優質的安卓開源項目,方便安卓開發人員便捷的找到自己需要的項目工具。 ...
  • 前言: 實現非同步下載apk文件 並 安裝。(進度條對話框顯示下載進度的展現方式) 涉及技術點: 1、ProgressDialog 進度條對話框 用於顯示下載進度 2、AsyncTask 非同步任務的使用 耗時操作不能再主線程中進行 安卓開發_淺談AsyncTask 3、File 文件相關操作 將文件的 ...
  • 工具 常見的反編譯工具我已經放到開源中國了,大家可以自行下載。 http://git.oschina.net/zyj1609/AndroidReverseProject 博客 這裡引用郭神的大作: Android安全攻防戰,反編譯與混淆技術完全解析(上) Android安全攻防戰,反編譯與混淆技術完 ...
  • block(代碼塊) 1.1 什麼是block block是iOS中一種比較特殊的數據類型。(可以定義變數、做形參或返回值) block是蘋果官方特別推薦使用的數據類型,應用場景比較廣泛 動畫 多線程 集合遍歷 網路請求回調 動畫 多線程 集合遍歷 網路請求回調 在多線程和網路也使用得相當頻繁,一般 ...
  • 分類 Category 分類只能給類擴充方法,不能添加屬性! Category有很多種翻譯:分類 / 類別 / 類目(一般叫分類) 分類是一個類的補充,是類的一部分。 Category的作用: 可以在不修改原來類的基礎上,為這個類擴充一些方法。(使用繼承也可以,在子類中擴充父類沒有的方法) 一個龐大 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...