OC基礎day05
繼承的簡單使用
- 代碼中的繼承是什麼意思?
- 繼承是一個創建類的方式,當想要創建一個B類,但是不想寫B中的成員,發現A中有自己想要的成員,這個時候就可以用繼承關係 把A類中的所有成員繼承過來
- 幾個名詞
- 類B的繼承自類A B類叫做A類的子類/派生類
- A類叫做B類的父類/基類
- 繼承是類在繼承問不是對象在繼承
- 繼承是類在繼承而不是對象在繼承
- 父類對象與子類對象是毫無關係的
- 什麼時候使用繼承
- 當發現A類中的成員 B類也想有 就讓B類繼承A類
- 繼承需要合理性
- 必須滿足 is a 關係的兩個類才能繼承
- 比如 狗類 可以繼承 動物
- 只要成員不是所有子類都擁有的就不應該定義在父類中
- OC繼承的特點
- 用繼承方式創建類的有什麼特點?
- 單根性/單繼承性,OC中一個類只能有一個父類
- 傳遞性, C類繼承自B類, B類繼承自A類 那麼C類擁有A的所有屬性方法(即子類擁有父類和父類的父類的所有屬性和方法)
- 用繼承方式創建類的有什麼特點?
NSObject類
- **NSObject是什麼?
- 是一個類 是所有類的根類
- 爲什麼要繼承NSObject
- 因爲所有的類需要創建對象 需要一個new來創建對象 new方法就是在NSObject中定義的
- 還有 new dealloc description… 都在NSObject類中
super 關鍵字
- 在子類的對象方法中需要調用從父類繼承過來的對象方法
- [self 方法名]
- [super 方法名]; 顯示告訴程序員這個方法是從父類繼承過來的
- 在類方法中使用 super關鍵字
- 在子類的類方法中需要調用從父類繼承過來的類方法
- [子類名 類方法名];
- [父類名 類方法名];
- [self 類方法名];
- [super 類方法名]; 顯示告訴程序員是從父類繼承過來的類方法
- 所以以後早子類中 需要調用從父類繼承過來的方法 就要用 super 更爲簡單 易懂
- super關鍵字 不能訪問屬性 只能調用方法
* 屬性的訪問修飾符*
- 是什麼
- @public 公共的
- @protected 受保護的 默認的
- @private 私有的
- @pachage 框架級別
- 有什麼用
- 在類的.h 文件中的屬性聲明 用着四中關鍵字聲明 可以限制屬性在當前類和子類中的訪問權限
分別有什麼用
- 無論是什麼屬性的修飾符都會被子類繼承
- 內部: 就是在當前類的方法中
- 外部: 就是在main函數中通富哦該類的對象訪問
- 修飾符的權限從大到小
- @public > @package > @protected > @private
- @public
- 在所有的程序中都能訪問
- @protected
- 在本類的內部可以直接訪問,外部不能直接訪問
- 在子類的內部可以直接訪問,外部不能直接訪問
- @private
- 在本類的內部可以直接訪問,外部不能
- 在子類的內部不能直接訪問, 外部不能
- 訪問修飾符的作用於
- 從定義修飾符開始到下一個出現或者大括號結束
私有屬性和真私有放大的應用
- 真私有屬性
- 在@private修飾的屬性 私有屬性
- 寫在.m的@implementation大括號中的屬性 真私有屬性
- 私有屬性和真私有屬性唯一的區別 Xcode不會提示
- 建議使用:
- 以後寫一個類 一把會有兩種屬性
- 一種在.h中用@protected修飾的屬性
- 一種在.m中的真私有屬性
- 私有方法
- 只在 .m中實現 不在.h中聲明
里氏替換原則 (縮寫 LSP)
- 一句話
- 父類的指針 可以指向子類的對象
里氏替換原則的好處
舉例: 人類 屬性:名字 行爲:喂狗,喂貓,餵豬(在實現中打印"xxx正在吃shi") 狗類,貓類,豬類 屬性:姓名
在main函數中 實現人餵豬,喂狗,喂貓的過程
里氏替換原則的侷限性
- 父類的指針 可以指向子類的對象
- 父類的指針 只能訪問子類從父類繼承過來的屬性和方法
- 不能訪問子類獨有的成員
方法重寫
- 什麼叫方法重寫
- 子類中重新實現父類繼承過來的方法
- 什麼時候需要方法重寫
- 父類繼承過來的方法 子類完全不適用 重寫方法
- 父類繼承過來的方法 子類需要補充 也需要方法重寫,
- 但是重寫方法的時候 要使用super關鍵字 [super 方法名]
- 先調用父類的方法 然後在添加自己想要的實現
- 如何重寫?
- 在 .m文件中 重新實現要重寫的方法 不是改聲明 也不需要再次聲明
強調
如果一個父類指針,指向了子類對象
如果通過父類的指針調用子類重寫的方法
那麼調用的是子類重寫後的方法
多態
- 多態 不同的事物 同一種行爲 不同的表現形式
- 一個多態滿足3各條件
- 有繼承關係
- 有方法重寫
- 有父類的指針 指向子類的對象
- 一個多態滿足3各條件
description 方法
- %@打印對象的原理
- 使用%@打印對象時, 內部的原理
- NSLog(@”%@”,對象名);
- 調用 [對象名 description]; 返回一個字符串
- 把這返回的字符串打印到控制檯
- 如果想要自定義打印出對象的格式 那麼需要重新這個description方法
* 繼承的本質*
- 子類會繼承所有的屬性的方法
- 子類創建對象的時候 會在堆區中開闢 只會開闢屬性所佔的空間
- 子類調用方法時, 方法的查找順序
- Student *stu = [Student new];
- [stu dercription];
- 首先會在本類中尋找 如果有直接調用
- 如果沒有 回想它直接父類中尋找 如果有直接調用
- 如果沒有 回繼續想上一級父類中尋找 如果還是沒有
- 會一直找,直到NSObject這個類 如果這個類還是沒有就報錯
類是一Class對象的形式存儲在代碼中的
@interface Person : NSObject
{
NSString *_name;
}
+ (void)sss;
- (void)sayHi;
@end
- 一個類在內存中是一Class對象的形式存儲的
- 那麼這個Class對象就是帶表這個類
- 如何獲取存儲這個類的Class對象
- 通過[對象名 class] 可以獲取到Class對象
- 通過[類名 class]可以獲取到這個Class對象
- Class對象 存儲了類的所有信息
- 也就是說Class對象 就代表了這個類
- Class cc = [Person class];
所以
- 使用Class對象調用類方法 [cc sss] 就可以直接調用類方法
- 使用Class對象 創建Pweson對象[cc new];
- 類的本質 就是一個對象 Class類型的對象
SEL數據
- 每一個類都有方法 其實方法在內存中也是以一種形式存在的
- 一個方法在內存中 是以 SEL這種數據類型存在的
//定義一個變量 來存儲一個方法 sayHi
SEL sayHiSel;//這是一個變量,這變量可以存儲方法
//@selector(方法名) 功能:根據一個方法名 返回一個SEL對象
sayHiSel = @selector(sayHi);