方法
同其他面向对象语言的成员方法,细节略有不同
实例方法
属于某个类实例,与类型方法相对应,实例化某个类实例出来之后,才可以使用类实例进行调用。(结构体与枚举也可以定义方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class Person
{
var name:String = "Jack"
var age:Int = 15
var education:String = "MiddleSchool"
// instance method
func introduceSelf()
{
print("Hello, Everyone! My name is \(self.name), I am \(age) years old.")
}
func growUp(age:Int, _ education:String)
{
self.age = age
self.education = education
}
}
let p = Person()
p.introduceSelf()
// 第一个参数不需要外部参数名,第二个及之后的需要外部参数名
p.growUp(18, "College")introduceSelf方法就是针对第个生成出来的Person的具体实例的,因为不同的person的属性是不同的。self与C++中的this意义相同,就指代当前的对象。
方法参数,Swift默认给除了第一个参数之外的参数一个外部参数名,不指定外部参数名的情况下与局部参数相同,这里Swift的默认行为,如果不想有外部参数名,可以使用_(下划线)显式忽略掉对应的外部参数名,这样就会覆盖掉Swift的默认行为。如上例中的growUp方法,显式忽略第二个参数的外部参数名。
值类型的实例方法不能修改实例属性, 结构体,枚举值类型的实例方法不能修改实例内部的属性,如果需要修改,需在方法前加可变的关键字mutating,否则会报错
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23struct Rect
{
var wid = 0, hgt = 0
mutating func modifyWid(wid:Int)
{
self.wid = wid
}
func modifyHgtTedt(hgt:Int)
{
// self.hgt = hgt 这里会报错
}
mutating func modifySelf(wid:Int, hgt:Int)
{
self = Rect(wid: wid, hgt: hgt)
}
}
var r = Rect(wid: 100, hgt: 100)
r.modifyWid(10)
print(r.wid) // 输出10
// 修改self的值
r.modifySelf(120, hgt: 30)
print(r.hgt) // 输出30可变方法中可以直接修改self的值,也就是自身实例的值可以在可变方法中直接修改。上例中的modifySelf方法,可直接给self赋值
类型方法
区别于实例方法,不需要生成实例即可调用,属性类级别的,直接使用ClassName.StaticMethod()的形式调用即可。方法定义使用static在func关键字前面。
1
2
3
4
5
6
7
8
9
10class StaticTest
{
static var staticInt:String = "Static Variable"
static func ClassTypeMethod()
{
print(self.staticInt)
}
}
// 直接使用类名调用
StaticTest.ClassTypeMethod()同类型差不多,如果需要子类重写对应的类型方法,不使用static而使用class关键字
下标
Swift中可以自定义类的中括号的实现,类似字典和数组那样的形式,使用subscript关键字,参数没有限制(包括个数与类型都没有限制),内部实现就像getter与setter。
下标语法
就像多了一层大括号的setter与getter实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class Test
{
subscript(row:Int, col:Int, ex:String) -> String
{
set{
print(newValue) // newValue的值类型必须与返回值类型相同,这里是String
}
get{
if row < 5 && col < 5
{
return "1 2 3 4"
}
else
{
return "More than 5"
}
}
}
}
let t = Test()
print(t[5, 3, "3"])
t[3, 3, "4"] = "Test"下标使用事项
下标参数可以是变量或者变参,但是不是是inout类型的,数量类型不限,也不可以设置参数默认值。可以有多个下标实现,Swift会根据不同的入参类型进行判定调用哪一个。
继承
这个特性只有类有,结构体与枚举不存在继承这一说。Swift的类继承在定义类时,类名后使用:(冒号)后面是基类名。
1 | class SubClass:BaseClass |
基类
一个没有继承其他任何类的类就是基类,它可能不被继承,也可能被继承,上边例子里面的Person就是一个基类。
子类
通过上述语法继承一个基类,这个类就是子类,子类拥有基类的的所有特性,并且还可以继续添加子类自己的特性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27class Person
{
var name:String = "Jack"
var age:Int = 15
var education:String = "MiddleSchool"
func introduceSelf()
{
print("Hello, Everyone! My name is \(self.name), I am \(age) years old.")
}
func growUp(age:Int, education:String)
{
self.age = age
self.education = education
}
}
class Programmer:Person
{
var codingSkill = "code"
func codingWith(lang:String)
{
print("DO NOT TOUCH ME, I am coding with \(lang) language!")
}
}
let p = Programmer()
p.introduceSelf() // 继承了Person的属性和方法,正常调用
p.codingWith("Swift") // 自己添加的新行为,coding重写
子类可以把继承过来的计算属性/属性观察器(不能同时重写setter和属性观察器,setter里就可以观察到属性变化了),方法,下标,都按子类的规则重新实现,叫做重写。就是覆盖了基类的实现,再次调用的时候就是子类自己的实现。使用override关键字,访问基类使用super关键字,比如在重写的过程中,需要先调用一下基类的实现,可以直接使用super.implement()这种形式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50class Person
{
var name:String = "Jack"
var age:Int = 15
var education:String = "MiddleSchool"
var address:String
{
get{
return ""
}
}
func introduceSelf()
{
print("Hello, Everyone! My name is \(self.name), I am \(age) years old.")
}
func growUp(age:Int, education:String)
{
self.age = age
self.education = education
}
}
class Programmer:Person
{
// 重写了基类的address计算属性的get
override var address:String
{
get{
return "Computer"
}
}
var codingSkill = "code"
func codingWith(lang:String)
{
print("DO NOT TOUCH ME, I am coding with \(lang) language!")
}
override func introduceSelf()
{
super.introduceSelf() // 使用super来访问基类
print("... And I am a PROGRAMMER, I am changing the world!")
}
}
let person = Person()
person.introduceSelf()
print(person.address)
let p = Programmer()
p.introduceSelf() // 程序员的自我介绍与Person不同了
p.codingWith("Swift")
print(p.address)// 重写了计算属性的getter禁止重写
基类中使用final关键字,防止子类重写此特性。同样适用于计算属性,属性观察器,方法,下标,如果一个类不想被继承,直接在class关键字前使用final,类即不可以被继承。试图重写被final标记的属性,方法,下标,继续被final标记的类,都会直接报错。