Swift能实现多继承吗?

虽然多继承在C++中可以实现,但在Swift中,是不能够实现多继承的。但一个class可以遵循多个协议,只能继承一个父类。但值类型比如 struct , enum 就不存在继承这么一说,但还是可以遵循多个协议的。
Swift只支持协议多继承
如:

1
2
3
4
5
6
7
protocol ChildAB:ChildA,ChildB {

}
class MyClass: ChildAB {
func method() {
}
}


struct或class可遵循多个协议实现假“多继承”
比如以下片段给UIView扩展实现多个协议的方法:
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
protocol Blinkable {
func blink()
}

extension Blinkable where Self: UIView {
func blink() {
alpha = 1

UIView.animate(
withDuration: 0.5,
delay: 0.25,
options: [.repeat, .autoreverse],
animations: {
self.alpha = 0
})
}
}

// MARK: - Scalable

protocol Scalable {
func scale()
}

extension Scalable where Self: UIView {
func scale() {
transform = .identity

UIView.animate(
withDuration: 0.5,
delay: 0.25,
options: [.repeat, .autoreverse],
animations: {
self.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
})
}
}

这样,我们申明一个View的实例,那么可以调用blink,scale 等方法。
1
2
3
extension UIView: Scalable, Blinkable {}
aView.blink()
aView.scale()

多个协议扩展相同方法:对象方法调用时的菱形问题

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
protocol Root {
func method()
}

extension Root {
func method() {
print("Method from Root")
}
}

protocol ChildA: Root {}

extension ChildA {
func method() {
print("Method from ChildA")
}
}

protocol ChildB: Root {}

extension ChildB {
func method() {
print("Method from ChildB")
}
}

class MyClass: ChildA, ChildB {} // Error: Type 'MyClass' does not conform to protocol 'Root'

let classA = MyClass()
classA.method() //此刻会发生什么?

很明显编译不通过,由于ChildA ,ChildB 两协议都扩展了协议method方法,此刻模棱两可,程序不知道method方法被调用的时候执行的是哪个协议扩展的方法。

如何解决问题菱形?

在遵循该方法的类里,实现该协议的方法。不使用协议ChildA,ChildB默认的扩展方法,这样编译器就知道调用的是自身的method()方法

1
2
3
4
5
class MyClass: ChildA, ChildB {
func method() {
print("hello,it's MyClass")
}
}

尽量让协议的方法名不重名。在ChildA或者ChildB中扩展不同的实现方法,然后遵循协议的类或者结构体实现method方法根据需要调用methodA 还是methodB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
extension ChildA {
func methodA() {
print("Method from ChildA")
}
}

extension ChildB {
func methodB() {
print("Method from ChildB")
}
}

class MyClass: ChildA, ChildB {
func method() {
if 条件 {
methodA()
}else{
methodB()
}
}
}

评论