类别是物件导向很重要的一个概念,在开发游戏时也常用到它。
可以把它想像成一张角色设计图,里头可能定义了角色会具备的属性、能力。有了这张设计图後,我们可以制作角色出来,也就是将角色实体化,变成一个真实的角色物件 (object)。
Role
,具有头发颜色 hairColor
跟眼睛颜色 eyeColor
两种属性init
,可带入参数,并且在初始化时赋予 hairColor
及 eyeColor
值run
、跳 jump
class Role {
var hairColor: String
var eyeColor: String
init(hairColor: String, eyeColor: String) {
self.hairColor = hairColor
self.eyeColor = eyeColor
}
func run() {
print("run")
}
func jump() {
print("jump")
}
}
Role(hairColor: "orange", eyeColor: "blue")
可以创建一个实体,并且带入这个角色特有的参数。例如我们创建一个人类的角色实体 human
human.hairColor
取得实体的属性human.run()
可以执行方法let human = Role(hairColor: "black", eyeColor: "brown")
print("hair color: \(human.hairColor)")
print("eye color: \(human.eyeColor)")
human.run()
human.jump()
印出结果:
hair color: black
eye color: brown
run
jump
提到类别就不能少了继承的概念,当一个 A 类别继承了 B类别,则 B类别称为父类别,A类别称为子类别。子类别可以继承父类别的属性及方法,可以减少重复的程序码。
在 swift 里,使用继承的方式可以用 :
,将要继承的类别放在冒号後面,并且最多只能继承一个类别
例如,宣告一个新的勇者类别 Brave
,让它继承 Role
类别
override
,覆写原本的 run
方法fly
方法class Brave: Role {
override func run() {
print("run faster")
}
func fly() {
print("fly")
}
}
Brave
依然可以使用父类别 Role
中的属性及方法,并且多了自己专有的方法,除了跑、跳之外,还可以飞let brave = Brave(hairColor: "orange", eyeColor: "blue")
print("hair color: \(brave.hairColor)")
print("eye color: \(brave.eyeColor)")
brave.run()
brave.jump()
brave.fly()
印出结果:
hair color: orange
eye color: blue
run faster
jump
fly
协定 (protocol) 的概念,其实和 interface 的概念非常相像,是一个尚未实作的、抽象的概念
它可以跟类别一样定义一些属性及方法,但是并不会实作,也就是方法内没有内容。
SuperPower
的协定,让勇者来使用useSuperPower()
方法的实作protocol SuperPower {
func useSuperPower()
}
Brave
类别遵循 SuperPower
协定:
Role
类别後方,使用逗号 ,
,再加上 SuperPower
协定。useSuperPower()
方法的内容,让勇者具有瞬间移动的超能力class Brave: Role, SuperPower {
override func run() {
print("run faster")
}
func fly() {
print("fly")
}
func useSuperPower() {
print("move instantly!!")
}
}
let brave = Brave(hairColor: "orange", eyeColor: "blue")
brave.useSuperPower()
印出结果:
move instantly!!
Monster
,同样继承 Role
类别。我们希望勇者跟怪物同样都可以使用超能力,并且他们的超能力不同,因此我们将 Monster
也遵循 SuperPower
协定class Monster: Role, SuperPower {
func useSuperPower() {
print("fireball!!")
}
}
let monster = Monster(hairColor: "red", eyeColor: "red")
monster.useSuperPower()
印出结果:
fireball!!
useSuperPower()
了,并且具有不同种类的超能力。而最初创建的人类角色,没有遵循超能力协定 SuperPower
,因此也确实不能使用超能力。useSuperPower()
方法宣告在 Role
类别中,也不需要在一开始就定义他的方法内容,只需要宣告在抽象的协定中,并且只在使用到的地方实作方法即可。结构 (struct) 和类别 (class) 类似,可以宣告属性及方法,但是结构不能继承,不过它是可以使用协定的。
init
可以省略SuperPower
协定,并且实作 useSuperPower()
方法struct Brave: SuperPower {
var hairColor: String
var eyeColor: String
func fly() {
print("fly")
}
func useSuperPower() {
print("move")
}
}
let brave = Brave(hairColor: "orange", eyeColor: "blue")
print("hair color: \(brave.hairColor)")
print("eye color: \(brave.eyeColor)")
brave.fly()
brave.useSuperPower()
印出结果:
hair color: orange
eye color: blue
fly
move
从上述的范例,结构看起来感觉跟类别很像对吧,但是他们还是有差异的。
简单来讲,当我对一个结构的实体做修改,我可以确实只修改到它。
而当我对一个类别的实体做修改,有可能会有其他实体也一起被修改!原因是当修改类别的实体时,实际上是对它指向的位址做修改,当有其他实体也是指向同个位址时,就会一起被修改了。
structBrave2
做修改时,structBrave
还是维持原本的值 (blue)classBrave2
做修改时,classBrave
的值也变成新的值了 (green)struct StructBrave {
var hairColor: String
var eyeColor: String
}
class ClassBrave {
var hairColor: String
var eyeColor: String
init(hairColor: String, eyeColor: String) {
self.hairColor = hairColor
self.eyeColor = eyeColor
}
}
let structBrave = StructBrave(hairColor: "orange", eyeColor: "blue")
let classBrave = ClassBrave(hairColor: "orange", eyeColor: "blue")
var structBrave2 = structBrave
var classBrave2 = classBrave
structBrave2.eyeColor = "green"
classBrave2.eyeColor = "green"
print(structBrave.eyeColor)
print(classBrave.eyeColor)
印出结果:
blue
green
let
宣告实体,不能修改他的属性
let structBrave = StructBrave(hairColor: "orange", eyeColor: "blue")
let classBrave = ClassBrave(hairColor: "orange", eyeColor: "blue")
structBrave.eyeColor = "green" // 报错,不能修改常数
classBrave.eyeColor = "green" // 成功编译,因 var eyeColor: String 为变数
以上是今日的介绍~
明天将进入 swift 基础语法的最後一篇介绍,继续加油吧!
Golang 加点GCP – cloud function 如果想要开始做点其他事情,就必须脱离本机...
tags: 2021铁人赛 React 上一篇只画了一张图表,投资怎麽可能只需要看一张图呢?这边就再...
Day 3 的作业有没有写呢各位? 如果昨天有练习的话,应该觉得不会太难吧! 我们今天会用一样的方...
-服务组织控制(SOC) 服务组织控制(Service Organization Control ...
简介 Go 是由 Google 开发的程序语言,於2007发起,在2009正式推,2012年发布第一...