iOS开发初学者入门 | 第四章:深入了解Swift

在这一章节中,我们会更深入的了解Swift,苹果公司给开发者提供了一系列的方法和类,也就是常说的framework(框架),这些框架叫做Foundation。你可以从developer.apple.com上找到更多关于苹果公司框架的知识。然而,这些框架也有不够用的时候,这就需要你能够编写你自己的类(class)或方法(methods)。在这一章节中,我就学习如何编写你的自己的类(class)、对象(objects)和方法(methods)。掌握这些技能会让你制作更广泛的应用程序。

方法(Methods)

方法(Methods)是为了完成一个具体目标而组织在一起的一系列步骤。方法(Methods)和函数(functions)这两个概念非常相似。方法(Methods)是在一个类或者一个对象中,为完成一个目标组合在一起的一组步骤,而函数(functions)是为完成一个目标组合在一起的一组步骤,是独立存在的。这两个概念非常相似,成了同义词。我会经常听到人们在使用这两个单词时常常互换使用,甚至是他们想说的是一个方法,却使用了function函数这个单词。
能够编写自己的方法可以非常方便地代替一些重复的工作。如果你想写一个每天迎接造成的方法,会是这样子:

 func goodMorning ( ) {
     println("Good Morning")
 }

首先用func作为方法的开头,func用来声明新方法的开头,接着就是方法的名字,使用驼峰命名法命名。例如:
goodMorning( )

Page 97

方法名字后面跟着一对括号,接着就是左大括号,表示一个方法的开始,最后是右大括号,表示一个方法的结束。
为了能够提供一个更详细的决策过程,方法(Methods)可以接收外来的输入值(就是参数值)。例如,你要训练一个田径队,如果能够告诉你的运动员他们需要跑具体多远,可能会比较有帮助(跑步或者跑7英里)。

外来是输入值会改变最终的结果。这些外来的输入值叫做parameters(参数)。参数是外来的值,被传入到方法中。参数的名字和类型写在括号内,传入的参数的值也就是这些括号内的变量名的值。例如:

func goodMorning(name: String){
    println("Good Morning \(name)")
}�
//Good Morning NAME

先写参数名字,然后是冒号,冒号后面就是参数的类型,如果方法有多个参数,用逗号间隔每个参数:

func goodMorning(name: String, day: String){
    println("Good Morning \(name), Happy \(day)")
}
 //Good Morning NAME-VARIABLE-HERE, happy DAY-VARIABLE-HERE

在你的方法中,你可以想写多少代码就写多少代码,不过基于最佳实践原则,最好把相似功能的代码写成一个方法,然后使用时再调用它。把你的代码变成多个可重复使用的小方法,这个好习惯,会让你的更新代码时轻松不少。

你刚刚编写了goodMorning方法,但是如何使用这个方法呢?调用(calling)方法是指,一行可以触发方法执行的代码。调用方法非常简单,写下方法的名字后跟一对括号。及时你的括号里并没有参数,这对括号也要写上。例如,这个名字为goodNight的方法:

func goodNight () {
    println("Good Night") 
}

调用这个方法的代码是这样的:

goodNight()
// "Good Night"

Page 98 | Chapter 4 : Diving Deeper

这样就能调用goodNight了,执行goodNight里的步骤。但是如果你的方法有参数值,像是goodMorning,如果调用呢?有参数值的方法一般都长这样:

func goodMorning(name: String, day: String){
    println("Good Morning \(name), Happy \(day)")
}

//Good Morning NAME-VARIABLE-HERE, happy DAY-VARIABLE-HERE

调用goodMorning方法的代码是这样的:

goodMorning("Steve", day: "Saturday")
//Good Morning Steve, Happy Saturday

最后,如果你的方法有参数,但是调用的时候忘记提供参数了,你可以为这些参数设置默认值。如果在调用时没有提供参数,就会使用默认值作为执行时的变量值。是这样设置默认值的:首先在类型后面写一个等号,然后等号右边写上这个默认值。例如,下面的代码把nameday的默认值设置成“World”和“Day”:

func goodMorning(name: String = "World", day: String = "Day") {
     println("Good Morning \(name), Happy \(day)")
}

现在,调用时忘记提供参数值,方法中打印出的信息仍然是可读的:

goodMoring()
// Good Morning World, Happy Day

返回值(Return Values)

除了能够接收输入值,执行一系列步骤,方法(Methods)还能做更多事情,还能产生输出值。当一个方法提供了一个输出值,这个输出值叫做返回值(return value)。返回值是方法的最终结果,返回给调用者。一个返回值可以是任何类型的,不过返回值的类型必须在方法中声明:

func sum(a: Int,b: Int) -> Int {
     return a + b
 }

如果一个方法有返回值,必须在参数后面定义一下。返回类型(return type)是被返回来的变量的类型。为了定义返回值的类型,首先要写一个dash(英文输入法下的破折号),然后一个大于号,看起来像一个剪头,表示这个方法有返回值,剪头的右面是返回值的类型。最后,return关键词还要出现在方法中,return后面是要返回的变量。

Methods | Page 99

不管方法中的代码有多少行,return表示这个方法结束了,编译器在编译方法中的代码时,遇到return就结束编译,return后面的代码就会被忽略掉:

func calculateTip(bill: Float, percentage: Float)-> Float {
    var tip = bill * percentage
    return tip
 }

类(Classes)

假设你是一个建筑师,你刚刚签了一个合同,要在一个新的小区修建20个相似的房子。在你派出建筑工队之前,你必须要画一个房子的设计图。这份设计图将会展现房子的外表和功能。把这份设计图当做模板,就能制作出20个房子各自的设计图了。
使用设计图或者模板来建造物品能够节省时间,让后期维护工作更加简单。这个原则同样适用于创建虚拟对象。在Swift中起着设计图功能的叫做类(class)。类是一个对象(object)的设计图或模板,这个模板可以反复使用来创建虚拟对象。

一个类定义了对象的属性和行为。
属性就是对象具有的特征。属性(attributes)由properties定义,(properties也有属性的意思,所以我就用英文了,不知道该怎么翻译才不会有歧义啊),properties就是对象中的变量。一个房子的properties可能是外部颜色,街道号码,浴室的数量。
行为就是对象提供的方法。例如,方法可能是,把空调温度调整到68华氏度,打开车库的门,凯琪报警系统。
在Swift中创建你自己的类是非常简单的。如果你想为你的新房屋建设项目写一个类,它看起来会是这样:

 class House {

  }

类的名字的开头是大写英文字母,这样能让其他的开发者区分出这时一个类还是一个对象。对象和方法常常用一个小写字母开头。

属性(Properties)

给你自定义的类增加属性和声明一个变量非常相似。你可以给你的house class增加一些属性:

class House {
  var exteriorColor = "Brown"
  var currentAirTemp = 70
  var isGarageOpen = true
  var isAlarmEnabled = false 
}

Page 100 | Chapter 4 : Diving Deeper

你给类增加了4个属性,每个都设置了默认值。这意味着参数没有传入新值时,从这个类中建造的房子都会有一个褐色的外表,车库的门是开启的,报警系统是关闭的,空调设置的温度是70华氏度。

方法(Methods)

你也可以给你的类增加一些方法:

class House {

  var exteriorColor = "Brown"
  var currentAirTemp = 70
  var isGarageOpen = false
  var isAlarmEnabled = false

  func prepareForNighttime(){
      isGarageOpen = false
      isAlarmEnabled = true 
      currentAirTemp = 65
   }

  func prepareForDaytime(){
      isGarageOpen = true
      isAlarmEnabled = false 
      currentAirTemp = 70
    }

  }

创建一个对象(Creating an Object)

现在你已经为你的类(house class)定义了属性和方法,是时候来建造第一个房子了。为了从一个类中创建一个对象,你需要调用初始化方法(initializer method)。这个初始化方法是专门为了设置新对象而设计的。初始化方法有些像你第一次打开Mac时遇见的安装向导。

Creating an Object | Page 101

如果你的参数有默认值,那么就没有必要写初始化方法了,Xcode会为你创建一个。初始化方法是这样写的,先写一个类的名字,然后跟上一对括号,例如:
var myHouse: House = House()
或者也可写成这样:
var myHouse = House()
不管那种方法都可以创建一个新的房子叫做myHouse

获取属性(Accessing Properties)

用点语法可以获取属性的值,点语法是可以取值或赋值的格式。点语法始于一个对象:
var myHouse = House()
为了获取exteriorColor,先写变量名字,后面跟一个点,然后是exteriorColor

myHouse.exteriorColor
//Brown

exeriorColor返回是字符串"Brown",因为这个属性的默认值是"Brown"。
这个简单的格式也可以用于给属性赋值,为了赋值,需要增加一个等号,然后写上新的值:
myHouse.exteriorColor = "Blue"
这样就把exeriorColor的值改成了"Blue":

myHouse.exteriorColor = "Blue" 
println(myHouse.exteriorColor)
//"Blue"

当代码把exeriorColor的值改成"Blue"后,接下来的一行打印出了房子的exeriorColor值。

Page 102 | Chapter 4 : Diving Deeper

调用方法(Calling Methods)

调用house类中的方法直接写上类的方法名字即可:
myHouse.prepareForNighttime()
调用方法和之前你看到调用属性都是使用点方法。首先,你先写一个对象的名字,然后一个点,跟着你想调用的方法的名字,最后是一对括号。如果这个方法有参数,那么写上参数值,如果没有参数,写一个空着的括号即可。

子类(Subclasses)

当你在创建什么东西的时候,重复使用模板会比重新画草稿好的多。假设你想建造一个木屋,木屋和房子有很多的相似之处,不过也有一些不同的属性和行为。这时,你可以借用house类然后做一些改变,而不是去重现画一个设计图。这个重新使用的过程就叫做子类化(subclassing)。
子类化能够使子类和父类之间简便地分享属性和行为。在这个例子中,父类是House,而子类是Cabin。写一个子类和创建一个类差不多,不同的是先有子类的名字,然后一个冒号,父类的名字是在冒号之后。例如:

class Cabin: House {

}

继承(Inheritance)

继承是指的父类的属性和行为能够传递给子类。所有父类的属性和行为都会自动地传递给子类。例如,cabin类继承了exteriorColor, currentAirTemp, isGarageOpen,和isAlarmEnabled的属性以及属性的默认值。cabin类还继承了prepareForNighttime()prepareForDaytime()两个方法。然而,如果有需要,cabin类可以增加或者修改这些属性值。例如,cabin类可能想把exteriorColor的默认值设置成"Red"。

Subclasses | Page 103

重构重写(Overriding)

如果你不想要一个褐色的小木屋怎么办?没关系,有了重写(overriding)就可以实现了。在子类中改变继承来属性或方法就叫做重写。重写使子类可以用用自己的特定的属性和方法。为了重写一个方法,我们会在方法前面增加一个override关键词。

初始化重写(Overriding initializers)

你可以用初始化方法来重写属性的默认值。无论什么时候,创建一个新的对象后,都要调用初始化方法,这意味着你要写你的初始化方法和默认值:

class House {
    var exteriorColor = "Brown"
    var currentAirTemp = 70
    var isGarageOpen = false
    var isAlarmEnabled = false

    func prepareForNighttime(){
    isGarageOpen = false
    isAlarmEnabled = true 
    currentAirTemp = 65
  }

  func prepareForDaytime(){
    isGarageOpen = true
    isAlarmEnabled = false 
    currentAirTemp = 70
  }
}

class Cabin: House {
    override init(){
        super.init()
        exteriorColor = "Red"
    }
}

cabin类用init关键词定义了自己的初始化方法。因为cabin类是重写的House类的初始化方法,所以需要在方法开头加上override关键词。记住,House类的初始化方法是自动创建的。init关键词后面跟着一对空括号,然后是左大括号,后面写初始化方法的具体内容。
在有子类的情况下,在重现或者修改子类之前,父类的初始化方法要先被调用。就父类而言,使用super关键词。在子类的init方法中,写super.init()。这就能够调用父类的初始化方法了。一旦完成初始化,子类就可以自由地去重写和修改了。在这个例子中,cabin类把exteriorColor修改为"Red"。

page 104 | Chapter 4 : Diving Deeper

重写方法

除了能够重写子类的属性之外,你还可以重写子类的方法。例如,当你为cabin设置nighttime时,就和House类不太相同。在一个House里,你可能想关上车库的门,改变空调的温度,开启报警系统,然而,在一个cabin里,没有报警系统,也没有车库,你更想在壁炉中生火。重新方法需要用到override关键词:

class Cabin: House {
    override init(){
        super.init()
        exteriorColor = "Red"
}
    override func prepareForNighttime(){
        startFire()
    }
}

在这一章中,你了解了更多swift知识,学习了如何创建自己的类和方法,如何创建子类和重写,有了这些技能,你已经能够编写任何你需要的类了。你的知识正在变多,现在是时候把这些知识应用到实践中去了,继续我们的Race Car练习吧。

练习:Race Car(Exercise:Race Car)

练习请点击此链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,200评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,526评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,321评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,601评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,446评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,345评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,753评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,405评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,712评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,743评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,529评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,369评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,770评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,026评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,301评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,732评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,927评论 2 336

推荐阅读更多精彩内容

  • 123.继承 一个类可以从另外一个类继承方法,属性和其他特征。当一个类继承另外一个类时, 继承类叫子类, 被继承的...
    无沣阅读 1,363评论 2 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,517评论 18 139
  • Hello Word 在屏幕上打印“Hello, world”,可以用一行代码实现: 你不需要为了输入输出或者字符...
    restkuan阅读 3,137评论 0 5
  • 本章将会介绍 存储属性的初始赋值自定义构造过程默认构造器值类型的构造器代理类的继承和构造过程可失败构造器必要构造器...
    寒桥阅读 766评论 0 0
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,123评论 9 118