1.面向?qū)ο笕筇匦?br>
-封裝性
-繼承性
-多態(tài)性
2.什么是封裝
封裝性就是隱藏實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外公開接口。
3.為什么要進(jìn)行封裝?
//?1成員變量是public的,也就是公開的,我們不能控制外界如何賦值,外界有可能賦值一些臟數(shù)據(jù)
@interface?Gun?:?NSObject
{
@public//公開成員變量
int?_bulletCount;//子彈數(shù)量
}
@end
//可以利用封裝來(lái)解決這個(gè)問題
//封裝:是指隱藏對(duì)象的屬性和實(shí)現(xiàn)的細(xì)節(jié),僅對(duì)外提供公共的訪問方法
```
-類是數(shù)據(jù)與功能的封裝,數(shù)據(jù)就是成員變量,功能就類方法或?qū)ο蠓椒?/p>
-對(duì)數(shù)據(jù)的封裝,也就是對(duì)成員變量的封裝
-不封裝的缺點(diǎn):當(dāng)一個(gè)類把自己的成員變量暴露給外部的時(shí)候,那么該類就失去對(duì)該成員變量的管理權(quán),別人可以任意的修改你成員變量。
-封裝就是將數(shù)據(jù)隱藏起來(lái),只能用此類的方法才可以讀取或者設(shè)置數(shù)據(jù),不可被外部任意修改是面向?qū)ο笤O(shè)計(jì)本質(zhì)。降低了數(shù)據(jù)被誤用的可能性!,提高代碼的靈活性
---
4.封裝的好處
-好處
+將變化隔離
+提高安全性
-原則
+將不需要對(duì)外提供的內(nèi)容都隱藏起來(lái),把屬性都隱藏,提供公共的方法對(duì)其訪問
依賴關(guān)系
1.依賴關(guān)系
-可以簡(jiǎn)單的理解,就是一個(gè)類A使用到了另一個(gè)類B,而這種使用關(guān)系是具有偶然性的、臨時(shí)性的、非常弱的,但是B類的變化會(huì)影響到A;
+比如某人要過(guò)河,需要借用一條船,此時(shí)人與船之間的關(guān)系就是依賴;
+在iOS中表現(xiàn)在代碼層面,為類B作為參數(shù)被類A在某個(gè)method方法中使用;
#繼承
##1.繼承基本概念
-現(xiàn)實(shí)生活中的繼承


-交通工具類是一個(gè)基類(也稱做父類),通常情況下所有交通工具所共同具備的特性,如速度與額定?載人的數(shù)量
-按照生活常規(guī),我們來(lái)繼續(xù)給交通工具來(lái)細(xì)分類的時(shí)候,我們會(huì)分別想到有汽車類和飛機(jī)類等?等,汽車類和飛機(jī)類同樣具備速度和額定載人數(shù)量這樣的特性,而這些特性是所有交通工具所共有的,那么就可以讓汽車或飛機(jī)類繼承交通工具類,這樣當(dāng)建立汽車類和飛機(jī)類的時(shí)候我們無(wú)需再定義交通工具類(基類)中已經(jīng)有的成員和方法,而只需要?述汽車類和飛機(jī)類所特有的特性即可。
-飛機(jī)類和汽車類的特性是由在交通工具類原有特性基礎(chǔ)上增加而來(lái)的,那么飛機(jī)類和汽車類就是交通工具類的派生類(也稱做子類)。以此類推,層層遞增,這種子類獲得父類特性的概念就是繼承
-繼承的重要性
##2.OC中的繼承關(guān)系
-?B類繼承A類,那么B類將擁有A類的所有屬性和方法,此時(shí)我們說(shuō)A類是B類的父類,B類是A類的子類
-?C類繼承B類,那么C類將擁有B類中的所有屬性和方法,包括B類從A類中繼承過(guò)來(lái)的屬性和方法,此時(shí)我們說(shuō)B類是C類的父類,C類是B類的子類
-注意:
+基類的私有屬性能被繼承,不能在子類中訪問。
+?OC中的繼承是單繼承:也就是說(shuō)一個(gè)類只能一個(gè)父類,不能繼承多個(gè)父類
+子類與父類的關(guān)系也稱為isA(是一個(gè))關(guān)系,我們說(shuō)?子類isA父類,也就是子類是一個(gè)父類,比如狗類繼承動(dòng)物類,那么我們說(shuō)狗isA動(dòng)物,也就是狗是一個(gè)動(dòng)物。在如汽車?yán)^承交通工具,那么們說(shuō)汽車isA交工工具,也就是汽車是一個(gè)交通工具
+繼承的合理性:引用《大話西游》里的一句話來(lái)描述繼承的?!叭耸侨怂麐屔?妖是妖他媽生的!”
##3.OC中如何實(shí)現(xiàn)繼承
-在聲明子類的時(shí)候,在子類名稱后面通過(guò):父類名稱方式來(lái)實(shí)現(xiàn)繼承
```
@interface子類名稱:父類名稱
@end
#繼承相關(guān)特性
1.方法重寫
-在子類中實(shí)現(xiàn)與父類中同名的方法,稱之為方法重寫;
-重寫以后當(dāng)給子類發(fā)送這個(gè)消息的時(shí)候,執(zhí)行的是在子類中重寫的那個(gè)方法,而不是父類中的方法。
-如果想在子類中調(diào)用被子類重寫的父類的方法,可以通過(guò)super關(guān)鍵字
-使用場(chǎng)景:當(dāng)從父類繼承的某個(gè)方法不適合子類,可以在子類中重寫父類的這個(gè)方法。
2.繼承中方法調(diào)用的順序
-?1、在自己類中找
-?2、如果沒有,去父類中找
-?3、如果父類中沒有,就去父類的父類中
-?4、如果父類的父類也沒有,就還往上找,直到找到基類(NSObject)
-?5、如果NSObject都沒有就報(bào)錯(cuò)了
>+如果找到了就執(zhí)行這個(gè)方法,就不再往后查找了
3.繼承的注意事項(xiàng)
-子類不能定義和父類同名的成員變量,私有成員變量也不可以;因?yàn)樽宇惱^承父類,子類將會(huì)擁有父類的所有成員變量,若在子類中定義父類同名成員變量?屬于重復(fù)定義。
-?OC類支持單一繼承,不支持多繼承;也就是說(shuō)一個(gè)類只能有一個(gè)直接父類
-?OC類支持多層繼承,如下圖所示
多態(tài)基本概念
1.什么是多態(tài)?
-什么是多態(tài):多態(tài)就是某一類事物的多種形態(tài)
+貓:貓-->動(dòng)物
+狗:狗-->動(dòng)物
+男人:男人-->人-->高級(jí)動(dòng)物
+女人:女人-->人-->高級(jí)動(dòng)物
-程序中的多態(tài):父類指針指向子類對(duì)象
---
##2.多態(tài)的條件
-有繼承關(guān)系
-子類重寫父類方法
-父類指針指向子類對(duì)象
```
狗*g?=?[狗new];
動(dòng)物*a?=?[狗new];
貓*c?=?[貓new];
動(dòng)物*a?=?[貓new];
```
-表現(xiàn):當(dāng)父類指針指向不同的對(duì)象的時(shí)候,通過(guò)父類指針調(diào)用被重寫的方法的時(shí)候,會(huì)執(zhí)行該指針?biāo)赶虻哪莻€(gè)對(duì)象的方法
---
##3.多態(tài)的優(yōu)點(diǎn)
-多態(tài)的主要好處就是`簡(jiǎn)化了編程接口。`它允許`在類和類之間重用一些習(xí)慣性的命名,`而不用?為每一個(gè)新加的函數(shù)命名一個(gè)新名字。這樣,編程接口就是一些抽象的行為的集合,從而和實(shí)現(xiàn)接口的類的區(qū)分開來(lái)。
-多態(tài)也使得代碼可以分散在不同的對(duì)象中而不用`試圖在一個(gè)函數(shù)中考慮到所有可能的對(duì)象。`這樣使得您的代碼擴(kuò)展性和復(fù)用性更好一些。當(dāng)一個(gè)新的情景出現(xiàn)時(shí),您無(wú)須對(duì)現(xiàn)有的代碼進(jìn)行?改動(dòng),而只需要增加一個(gè)新的類和新的同名方法。
---
#多態(tài)的實(shí)現(xiàn)
##1.如何實(shí)現(xiàn)多態(tài)
-?Animal是父類,子類有Cat和Dog,子類分別重寫了父類中的eat方法;實(shí)例化對(duì)象的時(shí)候可以用下面的方法:
```
Animal?*animal?=?nil;
//實(shí)例化貓的對(duì)象
animal?=?[Cat?new];
[animal?eat];
//實(shí)例化狗的對(duì)象
animal?=?[Dog?new];
[animal?eat];
```
##2.多態(tài)的原理
-動(dòng)態(tài)綁定:
+動(dòng)態(tài)類型能使程序直到執(zhí)行時(shí)才確定對(duì)象的真實(shí)類型
+動(dòng)態(tài)類型綁定能使程序直到執(zhí)行時(shí)才確定要對(duì)那個(gè)對(duì)象調(diào)用的方法
-?OC不同于傳統(tǒng)程序設(shè)計(jì)語(yǔ)言,它可以在運(yùn)行時(shí)加入新的數(shù)據(jù)類型和新的程序模塊:動(dòng)態(tài)類型識(shí)別,動(dòng)態(tài)綁定,動(dòng)態(tài)加載
-?id類型:通用對(duì)象指針類型,弱類型,編譯時(shí)不進(jìn)行具體類型檢查
---
##3.多態(tài)的注意點(diǎn)
-?1)如果存在多態(tài),父類是可以訪問子類特有的方法
假設(shè)?子類Dog有一個(gè)特有的方法bark
[dog?bark];
Animal?*an2?=?[Dog?new];
[(Dog*)an2?bark];?//把父類的指針,強(qiáng)制類型轉(zhuǎn)換
```
-?2)如果不存在多態(tài),父類是不可以訪問子類特有的方法的
```
Animal?*an3?=?[Animal?new];
[(Dog*)an3?bark];?//錯(cuò)誤的,不能強(qiáng)制轉(zhuǎn)換
```
#自定義代碼段
##1.如何自定義代碼片段
-將代碼拖拽到code區(qū)域

-配置快捷鍵等信息

-使用快捷鍵


-練習(xí),自定義get方法快捷鍵


---
##2.如何導(dǎo)入代碼片段
-將下載好的代碼片段拷貝到:`/Users/LNJ/Library/Developer/Xcode/UserData/CodeSnippets`下
+注意將`LNJ`換為自己的用戶名

#點(diǎn)語(yǔ)法
##1.點(diǎn)語(yǔ)法基本使用
---
##2.點(diǎn)語(yǔ)法的本質(zhì)
-其實(shí)點(diǎn)語(yǔ)法的本質(zhì)還是方法調(diào)用
-當(dāng)使用點(diǎn)語(yǔ)法時(shí),編譯器會(huì)自動(dòng)展開成相應(yīng)的方法

-當(dāng)點(diǎn)語(yǔ)法使用在?“=“賦值符號(hào)左側(cè)的時(shí)候,點(diǎn)語(yǔ)法會(huì)被展開為setter方法的調(diào)用,其他情況(等號(hào)右側(cè)、直接使用)為點(diǎn)語(yǔ)法展開為getter方法的調(diào)用
---
##3.點(diǎn)語(yǔ)法注意
-點(diǎn)語(yǔ)法的本質(zhì)是方法的調(diào)用,而不是訪問成員變量,當(dāng)使用點(diǎn)語(yǔ)法時(shí),編譯器會(huì)自動(dòng)展開成相?應(yīng)的方法調(diào)用。
-切記點(diǎn)語(yǔ)法的本質(zhì)是轉(zhuǎn)換成相應(yīng)的對(duì)setter和getter方法調(diào)用,如果沒有set和get方法,則不能使用點(diǎn)語(yǔ)法。
-不要在getter與setter方法中使用本屬性的點(diǎn)語(yǔ)法
```
-?(void)?setAge:(int)age?{
//下面的代碼會(huì)引發(fā)死循環(huán)
self.age?=?age;
//編譯器展開后[self?setAge:age]
}
-?(int)?age?{
//下面的代碼會(huì)引發(fā)死循環(huán)
return?self.age;
//編譯器展開后[self???age]
}
--
#實(shí)例變量修飾符
##1.實(shí)例變量的作用域

-?1)@public?(公開的)在有對(duì)象的前?下,任何地方都可以直接訪問。
-?2)@protected?(受保護(hù)的)只能在當(dāng)前類和子類的對(duì)象方法中訪問
-?3)@private?(私有的)只能在當(dāng)前類的對(duì)象方法中才能直接訪問
-?4)@package?(框架級(jí)別的)作用域介于私有和公開之間,只要處于同一個(gè)框架中相當(dāng)于@public,在框架外部相當(dāng)于@private
---
##2.變量修飾符在子類中的訪問
-?1)@private私有成員是能被繼承,也不能被外部方法訪問。
-?2)@public公有成員能被繼承,也能被外部方法訪問。
-?3)@protected保護(hù)成員能夠被繼承,不能夠被外部方法訪問。
---
##3.實(shí)例變量作用域使用注意事項(xiàng)
-?(1)在@interface?@end之間聲明的成員變量如果不做特別的說(shuō)明,那么其默認(rèn)是protected的。
-?(2)一個(gè)類繼承了另一個(gè)類,那么就擁有了父類的所有成員變量和方法,注意所有的成員變量它都擁有,只是有的它不能直接訪問。例如@private的
---
#?description方法
##1.description基本概念
-?NSLog(@"%@",?objectA);這會(huì)自動(dòng)調(diào)用objectA的description方法來(lái)輸出ObjectA的描述信息.
-?description方法默認(rèn)返回對(duì)象的描述信息(默認(rèn)實(shí)現(xiàn)是返回類名和對(duì)象的內(nèi)存地址)
-?description方法是基類NSObject所帶的方法,因?yàn)槠淠J(rèn)實(shí)現(xiàn)是返回類名和對(duì)象的內(nèi)存地址,這樣的話,使用NSLog輸出OC對(duì)象,意義就不是很大,因?yàn)槲覀儾⒉魂P(guān)心對(duì)象的內(nèi)存地址,比較關(guān)心的是對(duì)象內(nèi)部的一些成變量的值。因此,會(huì)經(jīng)常重寫description方法,覆蓋description方法?的默認(rèn)實(shí)現(xiàn)
---
##2.description重寫的方法
-對(duì)象方法
```
/**對(duì)象方法:當(dāng)使用NSLog輸出該類的實(shí)例對(duì)象的時(shí)候調(diào)用*/
-(NSString?*)?description
{
return?[NSString?stringWithFormat:@"狗腿數(shù):%d,狗眼數(shù)%d\n",_legNum,_eyeNum];
}
```
-類方法
```
/**類方法:當(dāng)使用NSLog輸出該類的類對(duì)象的時(shí)候調(diào)用*/
+(NSString?*)?description
{
return?@"+開頭的description方法";
}
```
##3.description陷阱
-千萬(wàn)不要在description方法中同時(shí)使用%@和self,下面的寫法是錯(cuò)誤的
```
-?(NSString?*)description?{
return?[NSString?stringWithFormat:@"%@",?self];
}
```
-同時(shí)使用了%@和self,代表要調(diào)用self的description方法,因此最終會(huì)導(dǎo)致程序陷入死循環(huán),循?環(huán)調(diào)用description方法
-當(dāng)[NSString?stringWithFormat:@“%@”,?self];使用它時(shí),循壞調(diào)用,導(dǎo)致系統(tǒng)會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤。
-當(dāng)該方法使用NSLog(“%@”,self)時(shí)候,系統(tǒng)做了相關(guān)的優(yōu)化,循壞調(diào)用3次后就會(huì)自動(dòng)退出
---
#?getter/setter方法
##1.setter方法
-作用:用來(lái)設(shè)置成員變量,可以在方法里面過(guò)濾掉一些不合理的值
-命名規(guī)范:
+必須是對(duì)象方法
+返回值類型為void
+方法名必須以set開頭,而且后面跟上成員變量名去掉”_”?首字母必須大寫
+必須提供一個(gè)參數(shù),參數(shù)類型必須與所對(duì)應(yīng)的成員變量的類型一致
+形參名稱和成員變量去掉下劃線相同
-舉例:
```
如:如果成員變量為int?_age那么與之對(duì)應(yīng)seter方法為
-(void)?setAge:?(int)?age;
```
-?setter方法的好處
+不讓數(shù)據(jù)暴露在外,保證了數(shù)據(jù)的安全性
+對(duì)設(shè)置的數(shù)據(jù)進(jìn)行過(guò)濾
---
##2.getter方法
-作用:為調(diào)用者返回對(duì)象內(nèi)部的成員變量的值
-命名規(guī)范:
+必須是對(duì)象方法
+必須有返回值,返回值的類型和成員變量的類型一致
+方法名必須是成員變量去掉下劃線
+一定是沒有參數(shù)的
-舉例
```
如:如果成員變量為int?_age那么與之對(duì)應(yīng)geter方法為
-?(int)?age;
```
-?getter方法的優(yōu)點(diǎn):
+可以讓我們?cè)谑褂胓etter方法獲取數(shù)據(jù)之前,對(duì)數(shù)據(jù)進(jìn)行加工;
+比如雙十一活動(dòng),我們希望對(duì)全線商品的價(jià)格在原來(lái)的價(jià)格基礎(chǔ)上打五折,那么我們只要去改成品類的價(jià)格的getter方法就可以了,讓他返回的值為價(jià)格*?0.5
---
##3.getter/setter方法注意
-在實(shí)際的開發(fā)中,不一定set和get方法都會(huì)提?供,如果內(nèi)部的成員變量,比如學(xué)生的學(xué)號(hào)或計(jì)算出來(lái)的數(shù)據(jù)。這樣的數(shù)據(jù)只允許外界讀取,但是不允許修改的情況,則通常只提?供get方法而不?提供set方法
。
-成員變量名的命名以下劃線開頭,get方法名不需要帶下劃線
-成員變量名使用下劃線開頭有兩個(gè)好處
+與get方法的方法名區(qū)分開來(lái)
+可以和一些其他的局部變量區(qū)分開來(lái),下劃線開頭的變量,通常都是類的成員變量。當(dāng)我看到以下劃線開頭變量,那么他一定是成員變量
---
##4.練習(xí)
-設(shè)計(jì)一個(gè)K線類,有三個(gè)屬性,最高價(jià)格,最低價(jià)格,平均價(jià)格.要求可以設(shè)置和獲取這三個(gè)屬性
#?Self關(guān)鍵字
-?OC提?供了兩個(gè)保留字self和super
+?OC語(yǔ)言中的self,就相當(dāng)于C++、Java中的this指針。
-要理解什么是self,什么是成員變量,什么是對(duì)象方法,什么是類方法
-成員變量:成員變量是一個(gè)實(shí)例對(duì)象的具體狀態(tài)特征,并且這些狀態(tài)特征是可以改變的,如張三的年齡,身高,體重等
-對(duì)象方法:一個(gè)實(shí)例對(duì)象的行為,比如張三具有吃的行為,張三做出這樣行為的時(shí)候,有可能會(huì)影響,自身的某些狀態(tài)特征,比如張三吃可能會(huì)增加張三體重和身高。
-類方法:類方法是某個(gè)類的行為,可以直接通過(guò)類名調(diào)用;如果在類方法中需要使用某些數(shù)據(jù),必須通過(guò)參數(shù)傳入;它不能訪問成員變量。
---
##1.類方法中的self
-在整個(gè)程序運(yùn)行過(guò)程中,`一個(gè)類有且僅有一個(gè)類對(duì)象`。
-通過(guò)`類名`調(diào)用方法就是給這個(gè)`類對(duì)象`發(fā)送消息。
-類方法的self就是這個(gè)類對(duì)象
-在類方法中可以通過(guò)self來(lái)調(diào)用其他的類方法
-不能在類方法中去調(diào)用對(duì)象方法或成員變量,因?yàn)閷?duì)象方法與成員變量都是屬于具體的實(shí)例對(duì)象的。
//缺一張配圖
---
##2.對(duì)象方法中的self
-在整個(gè)程序運(yùn)行過(guò)程中,`對(duì)象可以有0個(gè)或多個(gè)`
-通過(guò)`對(duì)象`調(diào)用方法就是給這個(gè)`對(duì)象`發(fā)送消息
-對(duì)象方法中self就是調(diào)用這個(gè)方法的當(dāng)前對(duì)象。
-在對(duì)象方法中,可以通過(guò)self來(lái)調(diào)用本對(duì)象上的其他方法
-在對(duì)象方法中,可以通過(guò)self來(lái)訪問成員變量
//缺一張配圖
---
##3.全局變量成員變量局部變量
-全局變量:只要是有聲明它的地方都能使用
-成員變量:只能在本類和其子類的對(duì)象方法中使用
-局部變量:只能在本函數(shù)或方法中使用
-從作用域的范圍來(lái)看:全局變量>成員變量>局部變量
-當(dāng)不同的作用域中出現(xiàn)了同名的變量,內(nèi)部作用域的變量覆蓋外部作用域變量,所以同名變量的覆蓋順序?yàn)椋壕植孔兞扛采w成員變量,成員變量覆蓋全局變量
-如果在對(duì)象方法中出現(xiàn)與成員變量同名的局部變量,如果此時(shí)想使用該成員變量可以通過(guò)self->成員變量名的方式
---
##4.self總結(jié)
-誰(shuí)調(diào)用self所在的方法,那么self就是誰(shuí)
-?self在類方法中,就是這個(gè)類的類對(duì)象,全局只有一個(gè),可通過(guò)self調(diào)用本類中的其他類方法,但是不能通過(guò)self來(lái)調(diào)用對(duì)象方法或訪問成員變量
-?self在對(duì)象方法中,就是調(diào)用這個(gè)方法的那個(gè)對(duì)象,?可以通過(guò)self調(diào)用本類中其他的對(duì)象方法,訪問成員變量,但不能通過(guò)self調(diào)用本類的類方法。
-通過(guò)self調(diào)用方法的格式:[self方法名];
-通過(guò)self訪問成員變量格式:self->成員變量名
---
##5.self使用注意
-同時(shí)有對(duì)象方法和類方法存在的時(shí)候,self不會(huì)調(diào)錯(cuò)
-?self只能在方法中使用;不要使用self來(lái)調(diào)用函數(shù),也不可以在函數(shù)內(nèi)部使用self;
-使用self調(diào)用本方法,導(dǎo)致死循環(huán)調(diào)用。
---
#?Super關(guān)鍵字
##1.super基本概念
-?super是個(gè)編譯器的指令符號(hào),只是告訴編譯器在執(zhí)行的時(shí)候,去調(diào)誰(shuí)的方法.
>+?self是一個(gè)隱私參數(shù);
```
self?refers?to?the?object?receiving?a?message?inObjective-Cprogramming.
```
>+?super并不是隱藏的參數(shù),它只是一個(gè)“編譯器指示符”,它和self指向的是相同的消息接收者
```
super?is?a?flag?that?tells?the?compiler?to?search?for?the?method?implementation?in?a?very?different?place.?It?begins?in?the?superclass?of?the?class?that?defines?the?method?where?super?appears.
```
##2.super的作用
+?1.直接調(diào)用父類中的某個(gè)方法
+?2.super在對(duì)象方法中,那么就會(huì)調(diào)用父類的對(duì)象方法
super在類方法中,那么就會(huì)調(diào)用父類的類方法
-使用場(chǎng)合:
+子類重寫父類的方法時(shí)想保留父類的一些行為