面向對象整體歸納: html
Swift 不只可以面向過程編程,也可以面向對象編程(OOP)。面向對象其實就是「以對象爲核心」,把咱們的客觀世界想着是由一個個對象組成的,面向對象編程則爲對象提供了屬性和方法,屬性就是爲了描述對象的一些狀態,方法則是告訴你對象該作什麼。面向對象和核心就是「類」和「對象」!在我剛接觸編程的時候,其實我也很容易把這東西混淆了,你要也是剛接觸編程,能幫到你的,我以爲反而是時間。你要實在是有點難理解,就別去鑽牛角尖,也許明天由於某個東西你就會恍然大悟。超喜歡那種感受!編程
面向對象的三大特性: 繼承 多態 封裝 (封裝和繼承好理解,多態我在前面的博客中有提過,不理解能夠往前面翻翻去看一下)。swift
Swift 面向對象編程的有五個單元: 枚舉 結構體 類 擴展 協議 數組
從總體的一個功能上看Swift的 枚舉、結構體、類 三者具備徹底平等的地位。(在後面咱們會對這三者進行一個區分的)其餘的面向對象編程的語言中都蛀牙提供了類一種單元,而Swift則有三種,你們想一想,OC、Java等語言是面向對象編程的,Swift 是面向對象和過程均可以,Swift 是一門全新的語言,它才面世幾年,而OC都快三十年了。因此Swift不簡單,要是Swift剛出來那時候有人寫出一個 println("Hello World")(2.0以前的寫法) 就以爲它很簡單,你真的就錯了。Swift 不簡單,你說簡單估計是由於你也只研究到 print("Hello World"),哈哈......
ide
在Swift中,枚舉和結構體是值類型的,類是引用類型。值類型和引用類型的區別,咱們後面說,先知道這一點。函數
在Swift的類、結構體、枚舉中均可以定義(屬性、方法、下標、構造體、嵌套類型),下面咱們一個一個的用我小小的認識說一下它們,我也會給你們一些我看到的很不錯的博客連接,方便你們更好的掌握,理解Swift。學習
一:枚舉spa
Swift枚舉是用來管理一組值的,固然也是有限的。好比一年四季你能夠用枚舉來管理,寫個季節枚舉,裏面的值就是(春夏秋冬),還有性別(男女),再到咱們的項目中好比常常看到的在即時通信裏面的消息類型(文字,圖片,語音,系統消息)等等。好比下面的例子:.net
給你們看看咱們在OC中是怎麼定義枚舉的,你們對比着理解:指針
/** 發送的消息類型 */ enum ZxMessageType: Int { case MessageTypeUnknown = 0 // 未知 case MessageTypeSystem // 系統 case MessageTypeText // 文字 case MessageTypeImage // 圖片 case MessageTypeVoice // 語音 case MessageTypeVideo // 視頻 case MessageTypeFile // 文件 case MessageTypeLocation // 位置 case MessageTypeShake // 抖動 }
// OC 枚舉
/** * 消息類型 */ typedef NS_ENUM(NSInteger, TLMessageType){ MessageTypeUnknown, // 未知 MessageTypeSystem, // 系統 MessageTypeText, // 文字 MessageTypeImage, // 圖片 MessageTypeVoice, // 語音 MessageTypeVideo, // 視頻 MessageTypeFile, // 文件 MessageTypeLocation, // 位置 MessageTypeShake, // 抖動 };
順便給你們提一下,上面這兩種方式,是我本身的習慣,其實按照咱們最開始學的時候的方式去定義沒問題,只是在官方的定義中,OC和Swift都是上面例子的方式寫枚舉,這樣寫也有好處,有同行分析過了,連接這裏。
Swift枚舉和 C,OC 枚舉的區別: Swift的枚舉成員不會被分配一個默認的整數值,它的枚舉名自己就是一個枚舉實例和整數值之間可沒有任何的關係。
Swift的知識點還有:枚舉值和Switch語句 原始值 關聯值 等幾個方面,但我就不說了,說了也不會有前輩們總結的詳細,我把知識點連接給你們,裏面的內容足夠掌握 Swift的枚舉了!
二:類和結構體
把這兩個放在一塊兒,純粹是由於這兩個太像了,咱們先把區別羅列出來,剩下的二者都同樣。
1: 結構體是值類型,類是引用類型。
2: 結構體不支持繼承,不支持類型轉換。(值類型緣由)
3: 結構體不支持定義析構器。 (後面提析構器的時候說)
插入說個問題: 實例 和 對象 的問題,在之前的OC中,對象就是實例,實例就是對象。但在Swift 中,之前記得看書的時候說是有 類 的實例才能叫作 對象,而 結構體 和 枚舉 的實例只能叫作實例,不能叫作對象。我以爲應該是和它們之間的類型有關係,他們之間最主要的區別其實也都是圍繞着 值類型和引用類型展開的。
看看類的定義:
class name: super class { // code // 構造器 // 屬性 // 方法 // 下標 }
注意點:
1: 當咱們本身不爲結構體/類 提供構造器時,系統爲結構體生成兩個構造器,一個是無參數的構造器,一個初始化全部存儲屬性的構造器。若是但願用戶定義的構造器與系統提供的構造器同時存在,則不能直接在類中定義構造器,可用擴展來添加。
2: Swift 的屬性分爲兩類,存儲屬性 和 計算屬性 ,存儲屬性相似於OC中的實例變量,它用來保存類型自己或者實例變量的狀態數據。計算屬性至關於OC中用setter和getter合成的 property 屬性,它並不必定保存數據。
三:存儲和計算屬性
(一) 存儲屬性
Swift 定義存儲屬性的方法和定義它變量常量的方法相同,咱們就不累贅。
存儲屬性能夠分爲 實例存儲屬性 類型存儲屬性 兩類。這個能夠參考OC的實例方法和類型方法,實例變量和類型變量同樣的道理去理解。
注意點:
1 : 枚舉不能定義 實例存儲屬性, 類和結構體能夠。
2 : Swift 要求全部的存儲屬性都必須顯式的制定初始值,要麼你在定義的時候指定初始值,要麼你在構造器裏面指定初始值。
3 : 若是將存儲屬性的類型申明爲可選類型,系統就能夠將這些屬性的初始值設置爲 nil (你們必定注意,Swift的nil和OC的nil徹底不同,Swift的nil是一個肯定的值,叫缺失值,而OC的nil是一個不指向任何類型的指針)。
好比定義的一個 model;
class ZxUser: NSObject { var username:String = "" var userID:String = "" var nikename:String = "" var avatarURL:String = "" var motto:String = "" var phoneNumber:String = "" var pinyin:String = "" var initial:String = "" }
在存儲屬性裏面,咱們要注意的是這個,延遲存儲屬性,延遲存儲屬性是指在第一次調用時纔會被計算初始值的屬性,聲明延遲存儲屬性須要使用 Lazy 修飾符。
咱們OC裏面經常使用到的懶加載就是延時存儲屬性,咱們看一個具體的例子就明白了:好比咱們懶加載這個 ZxMessageModel 類型的數組,寫法以下:
lazy var dataArray: Array<ZxMessageModel> = { // 弱引用防止循環引用寫法 // [weak self] in // [unowned self] in // __weak typeof (self) Wself = self let dataArray:Array = Array<ZxMessageModel>() return dataArray }()
至於懶加載爲何這樣寫,有什麼好處,看下面的連接!
Swift 懶加載(lazy) 和 Objective-C 懶加載的區別
(二) 計算屬性
計算屬性只能定義成變量形式,也就只能用 var 修飾。
計算屬性就是至關於咱們 OC 和 JAVA中經過 setter 和 getter 合成的屬性(property屬性)是同樣的。
咱們在OC中常常會這樣用一個 property 屬性,在.h中聲明瞭這個屬性,在.m中咱們寫它的 set 或者 get 方法,而後在他們的 set 或者 get 方法裏面作一些操做,看下面的這個例子:
// 依據不一樣的條件判斷返回不一樣的值 var cellHeight:CGFloat{ get{ switch self.messageType! { case ZxMessageType(rawValue:2)!: return self.messageSize.height + 40 > 60 ? self.messageSize.height + 40 :60 case ZxMessageType(rawValue:3)!: return self.messageSize.height + 20; default: break } return 0 } }
// 依據不一樣的消息類型設置不一樣的 cellIndentify var messageType:ZxMessageType?{ get{ return self.messageType } set { switch messageType! { case ZxMessageType(rawValue:2)!: self.cellIndentify = "TextMessageCell"; case ZxMessageType(rawValue:3)!: self.cellIndentify = "ImageMessageCell"; case ZxMessageType(rawValue:4)!: self.cellIndentify = "VoiceMessageCell"; case ZxMessageType(rawValue:5)!: self.cellIndentify = "SystemMessageCell"; default: break } } }
學習連接:
四:屬性觀察者
willSet(newValue): 被觀察的屬性即將被賦值以前自動調用該方法。
didSet(oldValue): 被觀察的屬性被賦值完成以後自動調用該方法。
上面的形參名是Swift隱式爲它們提供的,你能夠在方法中直接調用,扣上面字眼去理解它們的定義和使用;
var nameString = ""{ willSet{
print("set value") } didSet{
print("did set value") } }
五:方法
方法這裏咱們就說一點,這個感受是很基礎的了,函數方法,說多了也沒意思。
使用static 或者 class 修飾的方法屬於該類型的類方法,是可使用該類型自己來調用。class 通常是在類裏面修飾, static 通常用在結構體和枚舉中修飾。
六:下標
全部的Swift 類型(結構體、枚舉、類)都支持定義下標,下標能夠做爲訪問對象,集合或者序列的簡化方式。
Swift使用 subscript 關鍵字定義下標。
看下面這個例子就明白它的做用了:
struct TimesTable { let multiplier: Int subscript(index: Int) ->Int { return multiplier * index } } // 在另外的方法裏面這樣調用,看輸出的結果 let threeTimesTable = TimesTable(multiplier: 3) print("sixtimes three is \(threeTimesTable[6])") // prints"six times three is 18"
七:可選鏈
Swit 的全部類型默認是不能接受nil值的,若是程序想讓某種數據類型可以接受nil值,則要將這種數據類型包裝成可選類型:
1:在原有類型的後面添加 ? ,這種可選類型必須強制解析才能得到被包裝的值。
2:在原有類型的後面添加 ! ,這種可選類型可有Swift隱式的解析被包裝的值。
其實你掌握了可選類型的使用,可選鏈就沒什麼難度了,下面具體用法下面連接講的很清楚:
八:構造器
構造器用於完成實例的構造過程,這個過程包括爲實例中的每一個存儲屬性社會中初始值和執行必要的準備和初始化任務, 與OC的構造器不一樣,Swift的構造器無需顯式的聲明返回值的類型,也無需顯式使用 return返回實例, Swift 的構造器構造出來的實例由系統隱式的返回。它的本質其實就是一個或者多個名爲 init 的函數。
九:可能失敗的構造器
有些時候,枚舉,結構體,類的構造可能不能成功的返回該類型的實例,好比你傳入的構造器參數數據無效等等,這時候就定義了"可能失敗的構造器"。
可能失敗的構造器使用 init? 或者 init!來進行定義,在這種構造個人執行體內返回使用 return nil 來表示構造失敗,該構造器返回了一個nil(缺失值)。
Swift 不容許定義兩個具備相同形式類別的構造器,即便一個是可能失敗的構造器,一個是普通的構造器。
後序的關於面向對象沒寫完的,還在製造中,有錯誤的地方歡迎指正,也能夠加我QQ。。一塊兒討論學習