Swift第三周學(xué)習(xí)心得
第三周主要學(xué)習(xí)了關(guān)于以下幾種知識(shí)
一、數(shù)組的三種重要方法
關(guān)于數(shù)組的運(yùn)用有三種重要的方法
1.過濾 (留下滿足要求的)
let array = [23, 37, 96, 55, 40, 92, 68, 88]
let newArray = array.filter { (n : Int) -> Bool in
return n > 50
}
print(newArray)
let newArray2 = array.filter { (n) -> Bool in
return n % 2 == 0
}
print(newArray2)
關(guān)鍵字-filter
2.映射 (對(duì)原來的數(shù)組進(jìn)行你給的要求的變化變成新的數(shù)組)
let array = [23, 37, 96, 55, 40, 92, 68, 88]
let newArray3 = array.map { (n : Int) -> Int in
return n * n
}
print(newArray3)
關(guān)鍵字-map
3.縮減(規(guī)約)
let result1 = array.reduce(0, combine: +) //初始值 縮減(規(guī)約)的方法
let result2 = array.reduce(0, combine: *)
let result3 = array[1..<array.count].reduce(array[0]) { $1 > $0 ? $1 : $0 }
print(result3)
關(guān)鍵字-reduce
二、閉包
如果函數(shù)的最后一個(gè)參數(shù)是閉包可以寫成尾隨閉包的形式
也就是將閉包放到函數(shù)參數(shù)的圓括號(hào)外面寫在一對(duì)花括號(hào)中
如果函數(shù)后面有尾隨閉包且函數(shù)的圓括號(hào)中沒有參數(shù)
那么函數(shù)的圓括號(hào)也可以省略(僅限于有尾隨閉包的場景)
閉包函數(shù)有很多種省略的方法
var array = ["game", "abacus", "hello", "cat", "good", "internationalization", "chaos", "dislike", "zealot", "young"]
array.sortInPlace {
if $0.characters.count == $1.characters.count {
return $0 < $1
}
return $0.characters.count < $1.characters.count
}
print(array)
三、集合
集合與數(shù)組一樣都是存放數(shù)據(jù)的方式,但不同的是集合內(nèi)存放的元素是不能重復(fù)的,并且他們的存儲(chǔ)也不是按順序存儲(chǔ)的,反而是通過哈希計(jì)算隨機(jī)存儲(chǔ)
var b : Set<Int> = [1, 2, 3, 1, 2, 5] //集合
var c : Set<Int> = [3, 5, 7, 9, 11]
print(b)
print(b.intersect(c)) //交集 b和c都有的
print(b.union(c)) //并集 b和c所有的
print(b.subtract(c)) //差集 b有c沒有
遍歷集合
for x in b{
print(x)
}
b.insert(6) //添加元素
b.remove(2) //刪除元素
四、字典
字典是存放鍵值對(duì)組合的容器
字典中的每個(gè)元素都是由兩個(gè)部分構(gòu)成,冒號(hào)前面是鍵,后面是值
var dict = ["abacus": "算盤", "abnormal": "異常", "hello": "你好", "good": "很好"]
//key --> value
//通過鍵值獲取對(duì)應(yīng)值(可空類型,因?yàn)榻o的鍵有可能沒有與之對(duì)應(yīng)的值)
print(dict["hello"]) //]后加感嘆號(hào),如果找不到值,程序就出錯(cuò)。
//添加元素
dict["shite"] = "嘟嘟"
//刪除元素
dict.removeValueForKey("hello") // or dict["hello"] = nil
//修改值就重新賦值
dict["good"] = "不好"
//遍歷一個(gè)字典
//遍歷字典中所有的值
for value in dict.values{
print(value)
}
//遍歷字典中所有的鍵
for key in dict.keys{
print("\(key) ---> \(dict[key])")
}
//最常用,通過元組獲得字典中的鍵和值。
for (key, value) in dict{
print("\(key) ---> \(value)")
}
五、函數(shù)
定義一個(gè)函數(shù)
func 函數(shù)名(參數(shù)列表) -> 返回類型{函數(shù)執(zhí)行體}
可以給函數(shù)的參數(shù)設(shè)定默認(rèn)值,如果調(diào)用函數(shù)的時(shí)候沒有給該參數(shù)賦值就直接使用默認(rèn)值
func sayhello(personName : String, _ alreadyHello : Bool = false) ->String{ // 可以加默認(rèn)值
//let hello = "hello, " + personName + "!"
//如果函數(shù)的返回類型不是void,那么函數(shù)中一定有return語句
//return "hello, " + personName + "!"
//return hello
if alreadyHello{
return "又是你" + personName + "!"
}
else {
return "hello" + personName
}
}
調(diào)用函數(shù),直接寫函數(shù)名字傳參數(shù) -- 函數(shù)名(參數(shù)組)
調(diào)用Swit的函數(shù)時(shí),在默認(rèn)情況下從第二個(gè)參數(shù)開始需要寫參數(shù)名
print(sayhello("qqq", true))
//沒給第二個(gè)參數(shù)賦值,直接使用默認(rèn)你。再寫上參數(shù)和默認(rèn)值一樣的也可以
print(sayhello("qq"))
//let str = sayhello("qq")
//print(str)
函數(shù)的參數(shù)名
函數(shù)名(外部參數(shù)名 內(nèi)部參數(shù)名 : 類型, 外部參數(shù)名 內(nèi)部參數(shù)名 : 類型)
如果不寫外部參數(shù)名,那么內(nèi)部參數(shù)名也就是外部參數(shù)名
可以用_來作為外部參數(shù)名表示省略外部參數(shù)名
func myMin(x : Int, _ y : Int) -> Int{ // 調(diào)用不想寫y 就在y前面寫 _ y 省略外部參數(shù)名
return x < y ? x : y
}
//調(diào)用函數(shù)寫外部參數(shù)名
print(myMin(3, 5))
函數(shù)的參數(shù)列表是可變的,稱可變參數(shù)列表,函數(shù)參數(shù)個(gè)數(shù)是任意個(gè)
func sum1(nums: Int...) -> Int{
var total = 0
for num in nums{
total += num
}
return total
}
print(sum1())
print(sum(1,2,3))
print(sum1(11,12,12,23,44,56))
六、類
1.定義類(如果你要用的類蘋果已經(jīng)提供了就直接進(jìn)入第2步)
0.發(fā)現(xiàn)類
- 在對(duì)問題的描述里面找名次和動(dòng)詞
- 名詞會(huì)成為類或者類中的屬性,動(dòng)詞會(huì)成為類中的方法
1.定義類
- 數(shù)據(jù)抽象(屬性)
- 行為抽象(方法)
- 初始化方法
訪問修飾符
- public(公開,別的項(xiàng)目也能用)
- interna(內(nèi)部的) - 默認(rèn)
- private(私有,外界不讓訪問)
- 修飾符可以加在類,屬性,方法前面,但公開只能先公開類,再公開別的
定義類就可以創(chuàng)建出新的類型
學(xué)生類
class Student {
// 變量定義到類的外面就叫變量 - variable
// 變量定義到類的里面就叫屬性 - property
// 數(shù)據(jù)抽象 - 找到和學(xué)生相關(guān)的屬性(找名詞)
var name: String
var age: Int
// 初始化方法(構(gòu)造方法/構(gòu)造器) - constructor
init(name: String, age: Int) {
self.name = name
self.age = age
}
// 函數(shù)寫到類的外面就叫函數(shù) - function
// 函數(shù)寫到類的里面就叫方法 - method
// 行為抽象 - 找到和學(xué)生相關(guān)的方法(找動(dòng)詞)
func eat() {
print("\(name)正在吃飯.")
}
func study(courseName: String) {
print("\(name)正在學(xué)習(xí)\(courseName).")
}
func watchJapaneseAV() {
if age >= 18 {
print("\(name)正在觀看島國愛情動(dòng)作片.")
}
else {
print("親愛的\(name), 我們推薦你觀看《熊出沒》")
}
}
}
步驟2: 創(chuàng)建對(duì)象(調(diào)用初始化方法)
let stu1 = Student(name: "駱昊", age: 35)
步驟3: 給對(duì)象發(fā)消息(通過給對(duì)象發(fā)消息來解決問題)
stu1.eat()
stu1.study("Swift程序設(shè)計(jì)")
stu1.watchJapaneseAV()
let stu2 = Student(name: "王大錘", age: 15)
stu2.eat()
stu2.study("中國近代史")
stu2.watchJapaneseAV()
類是面對(duì)對(duì)象編程很重要的部分。在我的理解中,面對(duì)對(duì)象編程的對(duì)象就是通過類具體化得到的。我們說的類事包含很多屬性方法的抽象的一個(gè)合集,我們從中具體化(創(chuàng)建)一個(gè)對(duì)象出來對(duì)它發(fā)消息,消息的內(nèi)容就是我們希望對(duì)象完成的事。
2.創(chuàng)建一個(gè)類基本上要經(jīng)過三個(gè)步驟
數(shù)據(jù)抽象-初始化所有存儲(chǔ)屬性-行為抽象
class Robot {
// 數(shù)據(jù)抽象
var answer : Int // 正確答案
var counter : Int // 猜的次數(shù)
var hint : String // 提示信息
//對(duì)所有存儲(chǔ)屬性都要初始化(有初始值,默認(rèn)值)
init(){
answer = Int(arc4random_uniform(100)) + 1
counter = 0
hint = ""
}
// 行為抽象
// 判斷
func judge(qqq : Int) -> Bool{
counter += 1
if qqq < answer{
hint = "大一點(diǎn)"
}
else if qqq > answer{
hint = "小一點(diǎn)"
}
else{
hint = "恭喜你猜對(duì)了!你總共猜了\(counter)次"
return true
}
return false
}
}
swift里把得到某個(gè)值的方法就用名次做方法名,但也能寫成如下
通常獲得某個(gè)計(jì)算出來的值的方法都可以設(shè)計(jì)成計(jì)算屬性
計(jì)算屬性(通過對(duì)存儲(chǔ)屬性做運(yùn)算得到的屬性)
3.類的擴(kuò)展
類的擴(kuò)展也是很重要的一個(gè)部分
擴(kuò)展,不要改原來的類,神噩夢時(shí)候用就在用的地方擴(kuò)展
如果在某個(gè)特定的應(yīng)用場景中你發(fā)現(xiàn)現(xiàn)有的類缺少了某項(xiàng)功能
那么可以通過類的擴(kuò)展(extension)的方式現(xiàn)場添加這項(xiàng)功能
關(guān)鍵字 extension 類名
extension Point{
var cgPoint: CGPoint{
get {
return CGPointMake(CGFloat(x), CGFloat(y))
}
}
}
class Triangle {
var va: Point
var vb: Point
var vc: Point
var color : UIColor?
init(va : Point, vb: Point, vc: Point){
self.va = va
self.vb = vb
self.vc = vc
}
var perimeter: Double{
get{
let ab = va.distentsTo(vb)
let bc = vb.distentsTo(vc)
let ac = vc.distentsTo(va)
return ab + bc + ac
}
}
var area: Double{
get{
let ab = va.distentsTo(vb)
let bc = vb.distentsTo(vc)
let ac = vc.distentsTo(va)
let halfp = perimeter / 2
return sqrt(halfp * (halfp - ab) * (halfp - bc) * (halfp - ac))
}
}
func draw(){
let bezierPath = UIBezierPath()
bezierPath.moveToPoint(va.cgPoint)
bezierPath.addLineToPoint(vb.cgPoint)
bezierPath.addLineToPoint(vc.cgPoint)
bezierPath.addLineToPoint(va.cgPoint)
//color?.set()
// if let color = color{
// color.set()
// }
// else{
// UIColor.blueColor().set()
// }
//let nowcolor = color == nil ? UIColor.blueColor() : color!
//如果為空用??后面的值,不為空就直接用??前面的值,也就是它本身的值
let currentColor = color ?? UIColor.blueColor()
currentColor.set()
// 上面寫法的升級(jí)版
//(color ?? UIColor.blueColor()).set()
bezierPath.stroke()
}
}
4.類的繼承
從已有的類創(chuàng)建出新類的過程
提供繼承信息的類稱為父類(超類/基類)
得到繼承信息的類稱為子類(派生類/衍生類)
通常子類除了得到父類的繼承信息還會(huì)增加一些自己特有的東西
所以子類的能力一定比父類更強(qiáng)大
繼承的意義在于子類可以復(fù)用父類的代碼并且增強(qiáng)系統(tǒng)現(xiàn)有的功能、
class Student: Person {
var major: String
init(name: String, age: Int, gender: Gender, major: String){
self.major = major
//
super.init(name: name, age: age, gender: gender)
}
func study(courseName: String){
print("\(name)是\(major)專業(yè)的學(xué)生")
print("\(name)是\(gender == .Male ? "男" : "女")")
print("\(name)正在學(xué)\(courseName)")
}
}
我們可以將子類型的對(duì)象賦值給父類型的變量(因?yàn)樽宇惛割愔g時(shí)is-a關(guān)系)
學(xué)生是人,老師是人,所以學(xué)生和老師的對(duì)象可以賦值給人類型的變量
如果要將父類型的變量轉(zhuǎn)換為子類型需要使用as運(yùn)算符進(jìn)行類型轉(zhuǎn)換
如果能夠確認(rèn)父類型的變量中就是某子類型的對(duì)象可以用as!進(jìn)行轉(zhuǎn)換
如果不能確定父類型的變量中時(shí)那種子類型可以用as?嘗試轉(zhuǎn)換
let p2: Person = Student(name: "klle", age: 21, gender: .Female, major: "計(jì)算機(jī)")
p2.eat()
(p2 as! Student).study("社會(huì)學(xué)")
if let tmp = p2 as? Teacher{
tmp.teach("Java")
}
else{
print("\(p2.name)不是老師!")
}
let p3 = Teacher(name: "ollp", age: 35, gender: .Male, title: "渣渣")
p3.eat()
p3.teach("補(bǔ)到")
注意
if let tmp = p2 as? Teacher
p2是Person類,我們定義一個(gè)tmp代表P2,嘗試將其轉(zhuǎn)換成tercher類,用If- As?的方法,如果能轉(zhuǎn),tmp就能調(diào)用teacher類的方法那些,不能轉(zhuǎn)換也不影響