Better

业精于勤荒于嬉

Idiomatic Kotlin: class delegates

Better's Avatar 2019-06-02 Kotlin

  1. 1. define and use
  2. 2. bummock
  3. 3. override
  4. 4. other
  5. 5. 参考

类代理,指的是可以用另外一个实现了这个接口的类来代理实现这个接口。
kotlin 在语言层中支持了类代理。

define and use

这里其实是对实现一个 接口的快速实现,所以需要接口,以及一些默认的实现者实现接口。然后在类中代理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface Bicycle {
fun bar(): String
fun wheel(): String
}

class NormalBicyle : Bicycle {
override fun bar(): String = "直杆"

override fun wheel(): String = "普通轮胎"
}

class MountainBicycle : Bicycle {
override fun bar(): String = "直杆"

override fun wheel(): String = "防爆豪华轮胎"
}

class MyBiycle : Bicycle by MountainBicycle()

bummock

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
50
// Bicycle.java
public interface Bicycle {
@NotNull
String bar();

@NotNull
String wheel();
}

// NormalBicyle.java
public final class NormalBicyle implements Bicycle {
@NotNull
public String bar() {
return "直杆";
}

@NotNull
public String wheel() {
return "普通轮胎";
}
}

// MountainBicycle.java
public final class MountainBicycle implements Bicycle {
@NotNull
public String bar() {
return "直杆";
}

@NotNull
public String wheel() {
return "防爆豪华轮胎";
}
}

// MyBiycle.java
public final class MyBiycle implements Bicycle {
// $FF: synthetic field
private final MountainBicycle $$delegate_0 = new MountainBicycle();

@NotNull
public String bar() {
return this.$$delegate_0.bar();
}

@NotNull
public String wheel() {
return this.$$delegate_0.wheel();
}
}

类代理,其实就是在类中申明了代理对象,然后在对应的方法调用处,使用代理类来实现
在抽象了一堆方法后,需要一个特殊的实列来实现这些方法,可以使用这种方式。

override

支持重载
重载某个方法或者变量,类调用的时候对应的方法和变量就是被重载后的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface Base {
fun printMessage()
fun printMessageLine()
}

class BaseImpl(val x: Int) : Base {
override fun printMessage() { print(x) }
override fun printMessageLine() { println(x) }
}

class Derived(b: Base) : Base by b {
override fun printMessage() { print("abc") }
}

fun main() {
val b = BaseImpl(10)
Derived(b).printMessage()
Derived(b).printMessageLine()
}

列子中Derived重载了printMessage(),所以打印结果是:

1
abc10

以这种方式重写的成员不会在委托对象的成员中调用 ,委托对象的成员只能访问其自身对接口成员实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interface Base {
val message: String
fun print()
}

class BaseImpl(val x: Int) : Base {
override val message = "BaseImpl: x = $x"
override fun print() { println(message) }
}

class Derived(b: Base) : Base by b {
// 在 b 的 `print` 实现中不会访问到这个属性
override val message = "Message of Derived"
}

fun main() {
val b = BaseImpl(10)
val derived = Derived(b)
derived.print()
println(derived.message)
}

Derived重载的变量message,但是代理对象却访问不了这个,所以在代理对象的print()中,还是访问的自己的message

1
2
BaseImpl: x = 10
Message of Derived

other

面向对象设计 object oriented paradigm

Delegation pattern is one of the design patterns in object oriented paradigm and it uses composition to achieve it.

模板代码 boilerplate code

Delegation pattern involves a lot of boilerplate code. Fortunately for us, Kotlin has first-class support for delegation as a language feature

参考

kotlinDoc-by
Idiomatic Kotlin: Class Delegates

This article was last updated on days ago, and the information described in the article may have changed.