1.面向?qū)ο笕筇匦?br>
-封裝性
-繼承性
-多態(tài)性
2.什么是封裝
封裝性就是隱藏實(shí)現(xiàn)細(xì)節(jié),僅對外公開接口神得。
3.為什么要進(jìn)行封裝?
//?1成員變量是public的,也就是公開的,我們不能控制外界如何賦值,外界有可能賦值一些臟數(shù)據(jù)
@interface?Gun?:?NSObject
{
@public//公開成員變量
int?_bulletCount;//子彈數(shù)量
}
@end
//可以利用封裝來解決這個(gè)問題
//封裝:是指隱藏對象的屬性和實(shí)現(xiàn)的細(xì)節(jié),僅對外提供公共的訪問方法
```
-類是數(shù)據(jù)與功能的封裝,數(shù)據(jù)就是成員變量灯节,功能就類方法或?qū)ο蠓椒?/p>
-對數(shù)據(jù)的封裝循头,也就是對成員變量的封裝
-不封裝的缺點(diǎn):當(dāng)一個(gè)類把自己的成員變量暴露給外部的時(shí)候,那么該類就失去對該成員變量的管理權(quán)绵估,別人可以任意的修改你成員變量炎疆。
-封裝就是將數(shù)據(jù)隱藏起來,只能用此類的方法才可以讀取或者設(shè)置數(shù)據(jù),不可被外部任意修改是面向?qū)ο笤O(shè)計(jì)本質(zhì)。降低了數(shù)據(jù)被誤用的可能性!国裳,提高代碼的靈活性
---
4.封裝的好處
-好處
+將變化隔離
+提高安全性
-原則
+將不需要對外提供的內(nèi)容都隱藏起來,把屬性都隱藏,提供公共的方法對其訪問
依賴關(guān)系
1.依賴關(guān)系
-可以簡單的理解形入,就是一個(gè)類A使用到了另一個(gè)類B,而這種使用關(guān)系是具有偶然性的缝左、臨時(shí)性的亿遂、非常弱的,但是B類的變化會影響到A渺杉;
+比如某人要過河蛇数,需要借用一條船,此時(shí)人與船之間的關(guān)系就是依賴是越;
+在iOS中表現(xiàn)在代碼層面耳舅,為類B作為參數(shù)被類A在某個(gè)method方法中使用;
#繼承
##1.繼承基本概念
-現(xiàn)實(shí)生活中的繼承
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150530_2.png)
![](http://7xj0kx.com1.z0.glb.clouddn.com/jcjgt.png)
-交通工具類是一個(gè)基類(也稱做父類),通常情況下所有交通工具所共同具備的特性倚评,如速度與額定?載人的數(shù)量
-按照生活常規(guī),我們來繼續(xù)給交通工具來細(xì)分類的時(shí)候,我們會分別想到有汽車類和飛機(jī)類等?等,汽車類和飛機(jī)類同樣具備速度和額定載人數(shù)量這樣的特性,而這些特性是所有交通工具所共有的,那么就可以讓汽車或飛機(jī)類繼承交通工具類浦徊,這樣當(dāng)建立汽車類和飛機(jī)類的時(shí)候我們無需再定義交通工具類(基類)中已經(jīng)有的成員和方法,而只需要?述汽車類和飛機(jī)類所特有的特性即可。
-飛機(jī)類和汽車類的特性是由在交通工具類原有特性基礎(chǔ)上增加而來的,那么飛機(jī)類和汽車類就是交通工具類的派生類(也稱做子類)天梧。以此類推,層層遞增,這種子類獲得父類特性的概念就是繼承
-繼承的重要性
##2.OC中的繼承關(guān)系
-?B類繼承A類盔性,那么B類將擁有A類的所有屬性和方法,此時(shí)我們說A類是B類的父類呢岗,B類是A類的子類
-?C類繼承B類冕香,那么C類將擁有B類中的所有屬性和方法蛹尝,包括B類從A類中繼承過來的屬性和方法,此時(shí)我們說B類是C類的父類悉尾,C類是B類的子類
-注意:
+基類的私有屬性能被繼承,不能在子類中訪問箩言。
+?OC中的繼承是單繼承:也就是說一個(gè)類只能一個(gè)父類,不能繼承多個(gè)父類
+子類與父類的關(guān)系也稱為isA(是一個(gè))關(guān)系,我們說?子類isA父類焕襟,也就是子類是一個(gè)父類陨收,比如狗類繼承動物類,那么我們說狗isA動物鸵赖,也就是狗是一個(gè)動物务漩。在如汽車?yán)^承交通工具,那么們說汽車isA交工工具它褪,也就是汽車是一個(gè)交通工具
+繼承的合理性:引用《大話西游》里的一句話來描述繼承的把兔。“人是人他媽生的,妖是妖他媽生的!”
##3.OC中如何實(shí)現(xiàn)繼承
-在聲明子類的時(shí)候唯欣,在子類名稱后面通過:父類名稱方式來實(shí)現(xiàn)繼承
```
@interface子類名稱:父類名稱
@end
#繼承相關(guān)特性
1.方法重寫
-在子類中實(shí)現(xiàn)與父類中同名的方法拜秧,稱之為方法重寫;
-重寫以后當(dāng)給子類發(fā)送這個(gè)消息的時(shí)候老赤,執(zhí)行的是在子類中重寫的那個(gè)方法轮洋,而不是父類中的方法。
-如果想在子類中調(diào)用被子類重寫的父類的方法抬旺,可以通過super關(guān)鍵字
-使用場景:當(dāng)從父類繼承的某個(gè)方法不適合子類,可以在子類中重寫父類的這個(gè)方法弊予。
2.繼承中方法調(diào)用的順序
-?1、在自己類中找
-?2开财、如果沒有,去父類中找
-?3汉柒、如果父類中沒有,就去父類的父類中
-?4、如果父類的父類也沒有,就還往上找,直到找到基類(NSObject)
-?5责鳍、如果NSObject都沒有就報(bào)錯(cuò)了
>+如果找到了就執(zhí)行這個(gè)方法碾褂,就不再往后查找了
3.繼承的注意事項(xiàng)
-子類不能定義和父類同名的成員變量,私有成員變量也不可以历葛;因?yàn)樽宇惱^承父類正塌,子類將會擁有父類的所有成員變量,若在子類中定義父類同名成員變量?屬于重復(fù)定義啃洋。
-?OC類支持單一繼承,不支持多繼承传货;也就是說一個(gè)類只能有一個(gè)直接父類
-?OC類支持多層繼承,如下圖所示
多態(tài)基本概念
1.什么是多態(tài)?
-什么是多態(tài):多態(tài)就是某一類事物的多種形態(tài)
+貓:貓-->動物
+狗:狗-->動物
+男人:男人-->人-->高級動物
+女人:女人-->人-->高級動物
-程序中的多態(tài):父類指針指向子類對象
---
##2.多態(tài)的條件
-有繼承關(guān)系
-子類重寫父類方法
-父類指針指向子類對象
```
狗*g?=?[狗new];
動物*a?=?[狗new];
貓*c?=?[貓new];
動物*a?=?[貓new];
```
-表現(xiàn):當(dāng)父類指針指向不同的對象的時(shí)候,通過父類指針調(diào)用被重寫的方法的時(shí)候宏娄,會執(zhí)行該指針?biāo)赶虻哪莻€(gè)對象的方法
---
##3.多態(tài)的優(yōu)點(diǎn)
-多態(tài)的主要好處就是`簡化了編程接口问裕。`它允許`在類和類之間重用一些習(xí)慣性的命名,`而不用?為每一個(gè)新加的函數(shù)命名一個(gè)新名字。這樣,編程接口就是一些抽象的行為的集合,從而和實(shí)現(xiàn)接口的類的區(qū)分開來孵坚。
-多態(tài)也使得代碼可以分散在不同的對象中而不用`試圖在一個(gè)函數(shù)中考慮到所有可能的對象粮宛。`這樣使得您的代碼擴(kuò)展性和復(fù)用性更好一些窥淆。當(dāng)一個(gè)新的情景出現(xiàn)時(shí),您無須對現(xiàn)有的代碼進(jìn)行?改動,而只需要增加一個(gè)新的類和新的同名方法。
---
#多態(tài)的實(shí)現(xiàn)
##1.如何實(shí)現(xiàn)多態(tài)
-?Animal是父類,子類有Cat和Dog,子類分別重寫了父類中的eat方法;實(shí)例化對象的時(shí)候可以用下面的方法:
```
Animal?*animal?=?nil;
//實(shí)例化貓的對象
animal?=?[Cat?new];
[animal?eat];
//實(shí)例化狗的對象
animal?=?[Dog?new];
[animal?eat];
```
##2.多態(tài)的原理
-動態(tài)綁定:
+動態(tài)類型能使程序直到執(zhí)行時(shí)才確定對象的真實(shí)類型
+動態(tài)類型綁定能使程序直到執(zhí)行時(shí)才確定要對那個(gè)對象調(diào)用的方法
-?OC不同于傳統(tǒng)程序設(shè)計(jì)語言,它可以在運(yùn)行時(shí)加入新的數(shù)據(jù)類型和新的程序模塊:動態(tài)類型識別,動態(tài)綁定,動態(tài)加載
-?id類型:通用對象指針類型,弱類型,編譯時(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ū)域
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_23.png)
-配置快捷鍵等信息
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_27.png)
-使用快捷鍵
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_31.png)
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_32.png)
-練習(xí),自定義get方法快捷鍵
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_28.png)
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_30.png)
---
##2.如何導(dǎo)入代碼片段
-將下載好的代碼片段拷貝到:`/Users/LNJ/Library/Developer/Xcode/UserData/CodeSnippets`下
+注意將`LNJ`換為自己的用戶名
![](http://7xj0kx.com1.z0.glb.clouddn.com/Snip20150529_33.png)
#點(diǎn)語法
##1.點(diǎn)語法基本使用
---
##2.點(diǎn)語法的本質(zhì)
-其實(shí)點(diǎn)語法的本質(zhì)還是方法調(diào)用
-當(dāng)使用點(diǎn)語法時(shí)巍杈,編譯器會自動展開成相應(yīng)的方法
![](http://7xj0kx.com1.z0.glb.clouddn.com/dyf.png)
-當(dāng)點(diǎn)語法使用在?“=“賦值符號左側(cè)的時(shí)候忧饭,點(diǎn)語法會被展開為setter方法的調(diào)用,其他情況(等號右側(cè)筷畦、直接使用)為點(diǎn)語法展開為getter方法的調(diào)用
---
##3.點(diǎn)語法注意
-點(diǎn)語法的本質(zhì)是方法的調(diào)用,而不是訪問成員變量,當(dāng)使用點(diǎn)語法時(shí),編譯器會自動展開成相?應(yīng)的方法調(diào)用词裤。
-切記點(diǎn)語法的本質(zhì)是轉(zhuǎn)換成相應(yīng)的對setter和getter方法調(diào)用,如果沒有set和get方法,則不能使用點(diǎn)語法。
-不要在getter與setter方法中使用本屬性的點(diǎn)語法
```
-?(void)?setAge:(int)age?{
//下面的代碼會引發(fā)死循環(huán)
self.age?=?age;
//編譯器展開后[self?setAge:age]
}
-?(int)?age?{
//下面的代碼會引發(fā)死循環(huán)
return?self.age;
//編譯器展開后[self???age]
}
--
#實(shí)例變量修飾符
##1.實(shí)例變量的作用域
![](http://7xj0kx.com1.z0.glb.clouddn.com/slblxsf.png)
-?1)@public?(公開的)在有對象的前?下,任何地方都可以直接訪問鳖宾。
-?2)@protected?(受保護(hù)的)只能在當(dāng)前類和子類的對象方法中訪問
-?3)@private?(私有的)只能在當(dāng)前類的對象方法中才能直接訪問
-?4)@package?(框架級別的)作用域介于私有和公開之間,只要處于同一個(gè)框架中相當(dāng)于@public,在框架外部相當(dāng)于@private
---
##2.變量修飾符在子類中的訪問
-?1)@private私有成員是能被繼承,也不能被外部方法訪問吼砂。
-?2)@public公有成員能被繼承,也能被外部方法訪問。
-?3)@protected保護(hù)成員能夠被繼承,不能夠被外部方法訪問鼎文。
---
##3.實(shí)例變量作用域使用注意事項(xiàng)
-?(1)在@interface?@end之間聲明的成員變量如果不做特別的說明,那么其默認(rèn)是protected的渔肩。
-?(2)一個(gè)類繼承了另一個(gè)類,那么就擁有了父類的所有成員變量和方法,注意所有的成員變量它都擁有,只是有的它不能直接訪問。例如@private的
---
#?description方法
##1.description基本概念
-?NSLog(@"%@",?objectA);這會自動調(diào)用objectA的description方法來輸出ObjectA的描述信息.
-?description方法默認(rèn)返回對象的描述信息(默認(rèn)實(shí)現(xiàn)是返回類名和對象的內(nèi)存地址)
-?description方法是基類NSObject所帶的方法,因?yàn)槠淠J(rèn)實(shí)現(xiàn)是返回類名和對象的內(nèi)存地址,這樣的話,使用NSLog輸出OC對象,意義就不是很大,因?yàn)槲覀儾⒉魂P(guān)心對象的內(nèi)存地址,比較關(guān)心的是對象內(nèi)部的一些成變量的值拇惋。因此,會經(jīng)常重寫description方法,覆蓋description方法?的默認(rèn)實(shí)現(xiàn)
---
##2.description重寫的方法
-對象方法
```
/**對象方法:當(dāng)使用NSLog輸出該類的實(shí)例對象的時(shí)候調(diào)用*/
-(NSString?*)?description
{
return?[NSString?stringWithFormat:@"狗腿數(shù):%d,狗眼數(shù)%d\n",_legNum,_eyeNum];
}
```
-類方法
```
/**類方法:當(dāng)使用NSLog輸出該類的類對象的時(shí)候調(diào)用*/
+(NSString?*)?description
{
return?@"+開頭的description方法";
}
```
##3.description陷阱
-千萬不要在description方法中同時(shí)使用%@和self,下面的寫法是錯(cuò)誤的
```
-?(NSString?*)description?{
return?[NSString?stringWithFormat:@"%@",?self];
}
```
-同時(shí)使用了%@和self,代表要調(diào)用self的description方法,因此最終會導(dǎo)致程序陷入死循環(huán),循?環(huán)調(diào)用description方法
-當(dāng)[NSString?stringWithFormat:@“%@”,?self];使用它時(shí)周偎,循壞調(diào)用,導(dǎo)致系統(tǒng)會發(fā)生運(yùn)行時(shí)錯(cuò)誤撑帖。
-當(dāng)該方法使用NSLog(“%@”,self)時(shí)候,系統(tǒng)做了相關(guān)的優(yōu)化蓉坎,循壞調(diào)用3次后就會自動退出
---
#?getter/setter方法
##1.setter方法
-作用:用來設(shè)置成員變量,可以在方法里面過濾掉一些不合理的值
-命名規(guī)范:
+必須是對象方法
+返回值類型為void
+方法名必須以set開頭磷仰,而且后面跟上成員變量名去掉”_”?首字母必須大寫
+必須提供一個(gè)參數(shù)袍嬉,參數(shù)類型必須與所對應(yīng)的成員變量的類型一致
+形參名稱和成員變量去掉下劃線相同
-舉例:
```
如:如果成員變量為int?_age那么與之對應(yīng)seter方法為
-(void)?setAge:?(int)?age;
```
-?setter方法的好處
+不讓數(shù)據(jù)暴露在外,保證了數(shù)據(jù)的安全性
+對設(shè)置的數(shù)據(jù)進(jìn)行過濾
---
##2.getter方法
-作用:為調(diào)用者返回對象內(nèi)部的成員變量的值
-命名規(guī)范:
+必須是對象方法
+必須有返回值,返回值的類型和成員變量的類型一致
+方法名必須是成員變量去掉下劃線
+一定是沒有參數(shù)的
-舉例
```
如:如果成員變量為int?_age那么與之對應(yīng)geter方法為
-?(int)?age;
```
-?getter方法的優(yōu)點(diǎn):
+可以讓我們在使用getter方法獲取數(shù)據(jù)之前,對數(shù)據(jù)進(jìn)行加工境蔼;
+比如雙十一活動灶平,我們希望對全線商品的價(jià)格在原來的價(jià)格基礎(chǔ)上打五折,那么我們只要去改成品類的價(jià)格的getter方法就可以了箍土,讓他返回的值為價(jià)格*?0.5
---
##3.getter/setter方法注意
-在實(shí)際的開發(fā)中,不一定set和get方法都會提?供,如果內(nèi)部的成員變量,比如學(xué)生的學(xué)號或計(jì)算出來的數(shù)據(jù)逢享。這樣的數(shù)據(jù)只允許外界讀取,但是不允許修改的情況,則通常只提?供get方法而不?提供set方法
吴藻。
-成員變量名的命名以下劃線開頭,get方法名不需要帶下劃線
-成員變量名使用下劃線開頭有兩個(gè)好處
+與get方法的方法名區(qū)分開來
+可以和一些其他的局部變量區(qū)分開來,下劃線開頭的變量,通常都是類的成員變量瞒爬。當(dāng)我看到以下劃線開頭變量,那么他一定是成員變量
---
##4.練習(xí)
-設(shè)計(jì)一個(gè)K線類,有三個(gè)屬性,最高價(jià)格,最低價(jià)格,平均價(jià)格.要求可以設(shè)置和獲取這三個(gè)屬性
#?Self關(guān)鍵字
-?OC提?供了兩個(gè)保留字self和super
+?OC語言中的self,就相當(dāng)于C++沟堡、Java中的this指針侧但。
-要理解什么是self,什么是成員變量航罗,什么是對象方法禀横,什么是類方法
-成員變量:成員變量是一個(gè)實(shí)例對象的具體狀態(tài)特征,并且這些狀態(tài)特征是可以改變的粥血,如張三的年齡柏锄,身高酿箭,體重等
-對象方法:一個(gè)實(shí)例對象的行為,比如張三具有吃的行為趾娃,張三做出這樣行為的時(shí)候缭嫡,有可能會影響,自身的某些狀態(tài)特征抬闷,比如張三吃可能會增加張三體重和身高妇蛀。
-類方法:類方法是某個(gè)類的行為,可以直接通過類名調(diào)用笤成;如果在類方法中需要使用某些數(shù)據(jù)讥耗,必須通過參數(shù)傳入;它不能訪問成員變量疹启。
---
##1.類方法中的self
-在整個(gè)程序運(yùn)行過程中古程,`一個(gè)類有且僅有一個(gè)類對象`。
-通過`類名`調(diào)用方法就是給這個(gè)`類對象`發(fā)送消息喊崖。
-類方法的self就是這個(gè)類對象
-在類方法中可以通過self來調(diào)用其他的類方法
-不能在類方法中去調(diào)用對象方法或成員變量挣磨,因?yàn)閷ο蠓椒ㄅc成員變量都是屬于具體的實(shí)例對象的。
//缺一張配圖
---
##2.對象方法中的self
-在整個(gè)程序運(yùn)行過程中荤懂,`對象可以有0個(gè)或多個(gè)`
-通過`對象`調(diào)用方法就是給這個(gè)`對象`發(fā)送消息
-對象方法中self就是調(diào)用這個(gè)方法的當(dāng)前對象茁裙。
-在對象方法中,可以通過self來調(diào)用本對象上的其他方法
-在對象方法中节仿,可以通過self來訪問成員變量
//缺一張配圖
---
##3.全局變量成員變量局部變量
-全局變量:只要是有聲明它的地方都能使用
-成員變量:只能在本類和其子類的對象方法中使用
-局部變量:只能在本函數(shù)或方法中使用
-從作用域的范圍來看:全局變量>成員變量>局部變量
-當(dāng)不同的作用域中出現(xiàn)了同名的變量晤锥,內(nèi)部作用域的變量覆蓋外部作用域變量,所以同名變量的覆蓋順序?yàn)椋壕植孔兞扛采w成員變量廊宪,成員變量覆蓋全局變量
-如果在對象方法中出現(xiàn)與成員變量同名的局部變量矾瘾,如果此時(shí)想使用該成員變量可以通過self->成員變量名的方式
---
##4.self總結(jié)
-誰調(diào)用self所在的方法,那么self就是誰
-?self在類方法中箭启,就是這個(gè)類的類對象壕翩,全局只有一個(gè),可通過self調(diào)用本類中的其他類方法傅寡,但是不能通過self來調(diào)用對象方法或訪問成員變量
-?self在對象方法中放妈,就是調(diào)用這個(gè)方法的那個(gè)對象,?可以通過self調(diào)用本類中其他的對象方法荐操,訪問成員變量芜抒,但不能通過self調(diào)用本類的類方法。
-通過self調(diào)用方法的格式:[self方法名];
-通過self訪問成員變量格式:self->成員變量名
---
##5.self使用注意
-同時(shí)有對象方法和類方法存在的時(shí)候,self不會調(diào)錯(cuò)
-?self只能在方法中使用;不要使用self來調(diào)用函數(shù)托启,也不可以在函數(shù)內(nèi)部使用self宅倒;
-使用self調(diào)用本方法,導(dǎo)致死循環(huán)調(diào)用驾中。
---
#?Super關(guān)鍵字
##1.super基本概念
-?super是個(gè)編譯器的指令符號,只是告訴編譯器在執(zhí)行的時(shí)候,去調(diào)誰的方法.
>+?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在對象方法中,那么就會調(diào)用父類的對象方法
super在類方法中唠亚,那么就會調(diào)用父類的類方法
-使用場合:
+子類重寫父類的方法時(shí)想保留父類的一些行為