標籤:
不管做什麼事,只要敬業點,把該作的做好。不要總找借口。不要看不起小事,生活本是一件件小事的集合。細節決定成敗。士兵突擊裡面有句台詞:他每做一件小事的時候,都好像抓住了一根救命稻草,到最後你才發現,他抱住的已經是一顆參天大樹。
七、物件導向
swift可以定義
物件導向類型: 枚舉 結構體 類 ,可以定義變數,枚舉,結構體是實值型別,類定義變數是參考型別
以上三種都支援定義儲存屬性,計算屬性,方法,下標,構造器,巢狀型別。
JAVA支援的特性,swift都支援,不支援的,它也支援,文法簡潔,但功能並不簡單,反而很強大!
OOP :Object Oriented Programming 以對象為中心編程
對象總有狀態和行為,對應的:
屬性:描述對象的狀態
方法:描述對象的行為
物件導向兩大核心:類和對象
類:具有共同特徵的對象的定義,如 人類, 對象是類的具體執行個體,你,我,喬布斯,雷蛋蛋
物件導向典型三大特徵:
封裝: 把對象的狀態資料,實現細節隱藏起來,只露出合適的方法,允許外部程式調用,改變程式狀態。 private ,internal public 限制封裝
繼承:複用已有的類,一般到特殊,蘋果繼承了水果,單繼承,通過協議來彌補不足
多態:
swift 的 類 結構體 枚舉 具有完全平等的地位
5種物件導向程式單元為:類,結構體,枚舉,擴充,協議
注意:執行個體和對象不同
執行個體:結構體和枚舉的執行個體
對象:類的執行個體
複雜的是:swift 中 類,結構體,枚舉的內部分別可以定義屬性(儲存屬性和計算屬性),方法,下標,構造器,巢狀型別(嵌套類,嵌套結構體,嵌套枚舉) 這5種類型成員!
真是讓人 要瘋了~
只有類支援繼承
人之為學有難易乎?為之,則難者亦易矣,不為,則易者亦難矣!
枚舉:管理一組有限的值的集合 enum 名字首字母大寫,連續駝峰命名法
比如季節 性別
不同的是:成員不會預設分配一個整數值
enum Weekday
{
case Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
}
調用
var chooseDay = Weekday.Saturday
switch(chooseDay)
{
case .Monday:
println("星期一")
case .Tuesday:
。。。類似 省略
}
原始值:可以使 Int ,Double,Float,Character,String 類型的值
enum Weekday :Int
{
case Monday,Tuesday = 1,Wednesday=5,Thursday,Friday,Saturday,Sunday
}
enum Season :Character
{
case Spring = "S"
。。。
}
屬性:rawValue 擷取指定枚舉值的原始值
var day = Weekday.Saturday
day.rawValue //8
關聯值:associated value
類似屬性,為每個枚舉值定義更多的資料,從而更好地描述該枚舉代表的執行個體的狀態。
enum Planet
{
case Mercury(weight:Doubel,density:Double,name:String)
case Earth(Double,String)
}
調用
var p1 = Planet.Mercury(weight:0.05,density:5.43,name:"水星")
類 官方說,主要是使用類
private internal public final
類定義,最常用的 構造器,屬性,方法
構造器:構造該類的執行個體
屬性:定義該類或該類的執行個體所包含的狀態資料
方法:定義該類或該類的執行個體的行為特徵或者功能實現
類名後邊()表示調用 構造器,從而返回該類的執行個體
計算屬性:執行個體變數
儲存屬性:檔案類型本身或執行個體的狀態資料
構造器 init 不能聲明傳回值類型 無需寫return
class Person
{
//定義儲存屬性
var name:String = ""
var age:Int = 0
//定義方法
func say(content:String)
{
println(content)
}
}
// 建立執行個體
var p:Person
// 調用構造器
p = Person()
//上邊兩句 簡寫 成
var p = Person()
// 執行個體的作用
1、訪問執行個體屬性
2、調用執行個體的方法
p.name = "renhairui"
p.say("swift是一門非常強大的語言")
大多數情況,定義一個類,就是為了重複建立類的執行個體,類是多個執行個體的共同特徵
假如用上邊的例子建立 結構體
struct Person
{
//定義儲存屬性
var name:String
var age:Int
//定義方法
func say(content:String)
{
println(content)
}
}
則
var my = Person(name:"renhairui",age:28)
println(my.name) // renhairui
假如調用無參數的構造器建立執行個體
var hello = Person()
則 hello.age 是0
參考型別比較 === !==
比較兩個參考型別的變數是否指向同一個執行個體
只有參考型別的變數才能用 這個!
self關鍵字 指向該方法的調用者
執行個體方法中:self代表 調用該方法的執行個體
類型方法中:self代表代用該方法的類型(類或者結構體)
class Dog
{
func jump()
{
}
func run()
{
self.jump() //允許執行個體的成員調用另一個成員,可以省略self jump()正確!
}
}
在方法中強制引用儲存屬性 用self
class wolf
{
var name :String = ""
var age:Int = 2
init (name:String,age:Int)
{
self.name = name
self.age = age
}
func info ()
{
println("我的名字是\(name),年齡是\(age)歲")
}
}
調用
var wolf = Wolf(name:"任海瑞",age:28)
wolf.info()
self 作為方法調用者時,可以訪問self,甚至當成傳回值
class ReturnSelf
{
var age:Int = 0
func grow()->ReturnSelf
{
age ++
return self
}
}
調用
var rt = ReturnSelf()
rt.grow()
.grow()
println(rt.age)
結構體:封裝少量相關的簡單資料值,該執行個體在賦值和傳遞時會自動複製副本
儲存屬性: 1定義是指定初始值,2構造器中定義初始值
延遲儲存 第一次被調用是才會被計算初始值的屬性,lazy
lazy load 當某個執行個體持有另一個建立成本比較大的執行個體的引用時,降低記憶體開銷,提升程式效能。
class Dept
{
var id:Int
var info:String
init (id:Int)
{
self.id = id
NSThread.sleepForTimeInterval(2)// 類比耗時操作
self.info = "類比讀取資料庫"
}
}
class User
{
var id:Int = 0
// 這個時候如果調用 Dept 則會建立較大成本執行個體 不能用 var dept = Dept(id :20)
lazy var dept = Dept(id:20)
var nicks = [String]()
}
//建立執行個體
var user =User()
user.nicks.append("孫悟空")
user.nicks.append("任海瑞")
println(user.nicks)
計算屬性:本質是 getter setter方法的組合
class User
{
var first:String = ""
var last:String = ""
var fullName:String
{
// 定義計算屬性的getter方法 傳回值由first,last兩個儲存屬性決定
return first +"-"+last
}
set(newValue){
// 改變first last兩個儲存屬性
var names = newValue.componentsSeparatedBystring("-") //字串切割成數組
self.first = names[0]
self.last = names[1]
}
}
init(first:String,last:String)
{
self.first =first
self.last = last
}
調用
let s = User(first:"海瑞",last:"任")
println(s.fullName) // 海瑞-任
s.fullName = "悟空-孫"
println(s.first) //悟空
println(s.last) //孫
setter方法提供隱式參數名 newValue 不用寫 直接用
set {
var names = newValue.componentsSeparatedBystring("-") //字串切割成數組
self.first = names[0]
self.last = names[1]
}
不寫setter方法 就是唯讀的計算屬性
屬性觀察者 willSet() didSet()
方法:行為特徵的抽象
函數:放在枚舉,結構體,類以外定義
方法:上邊三種內定義,枚舉,結構體中用static,類中用class,意思一樣
類型.方法
執行個體.方法
class SomeClass
{
func test(){ //方法}
class func bar(#msg:String)
{
println("bar類型方法,傳入參數:\(msg)")
}
}
用
var sc = SomeClass()
//sc的test分離成函數 注意:千萬不能加(),否則變成方法調用,不是將方法賦值給函數類型的變數
var f1:()->() = sc.test
var f2:(String)->Void = SomeClass.bar
// 下面兩個一樣
sc.test() f1()
SomeClass.bar(msg:"測試資訊") f2("測試資訊")
注意:結構體,枚舉的執行個體方法不能分離,轉換成函數,他們的類型方法才可以。
預設為方法除第一個參數外的其他形參都添加了外部形參名,不用寫外部參數名或者#了,比較人性化。
enum,stuct,class中的func是執行個體方法
命名習慣:
方法名,以動詞開頭,動詞+名詞(描述第一個參數的含義)
有時候還會在動詞和名詞之間 加 with,for ,by介詞,儘力把調用方法像一條簡單的英文句子
func indexOfObject()
可變方法
結構體和枚舉都是實值型別,預設情況下,執行個體方法不能改變執行個體的儲存屬性。
假如需要修改,則mutating 聲明為可變方法,可以在方法體內對隱式的self重新賦值
作用:改變枚舉,結構體的內部資料。
struct Rect
{
var x:Int
var y:Int
var width:Int
var height:Int
mutating func moveByx(x:Int,y:Int)
{
self.x += x
self.y += y
}
}
// 建立執行個體
var rect = Rect(x:20,y:12,width:200,height:300)
// 調用可變方法
rect.moveByx(100,y:80)
println("\(rect.x),\(rect.y)")
下標:可以訪問 對象,結婚,序列(枚舉,結構體,類都支援)
P175
swift學習筆記7