内容简介:一看题目,有点儿晕。看个例子马上就明白了:我们有这么一个类,一看就是要写 Builder 模式。不过由于我们的这个 Event 的类型比较多,因此希望写一个父类,来一个子类感受下:看上去也没啥大毛病,用一下吧:
一看题目,有点儿晕。看个例子马上就明白了:
abstract class EventBuilder() {
protected var retryLimit = 3
fun retryLimit(retryLimit: Int): EventBuilder {
this.retryLimit = retryLimit
return this
}
abstract fun build(): PollingEvent
}
我们有这么一个类,一看就是要写 Builder 模式。不过由于我们的这个 Event 的类型比较多,因此希望写一个父类,来一个子类感受下:
class DisposableEventBuilder : EventBuilder() {
private var delay: Long = 0L
fun delay(delay: Long): DisposableEventBuilder {
this.delay = delay
return this
}
override fun build() = object: DisposableEvent(name, delay){
override fun onDisposableEvent() {
callback.onEvent(this)
}
}
}
看上去也没啥大毛病,用一下吧:
DisposableEventBuilder().retryLimit(3)
.delay(60_000) // ERROR!!
.build()
我们调用完父类的 retryLimit
方法后,想要设置下 delay
,结果发现没有这个方法。
“我 X,这什么玩意儿”,你嘟囔了一句。
因为返回的是父类,所以链式调用掉链子了。这就尴尬了。
2. Scala 的解法
如果这段代码用 Scala 写,那么用 this.type
就简直完美的解决了这个问题:
abstract class SuperBuilder {
private var retryLimit: Int = 0
def retryLimit(retryLimit: Int): this.type = {
this.retryLimit = retryLimit
this
}
}
class SubBuilder extends SuperBuilder {
private var delay: Long = 0
def delay(delay: Long): SubBuilder = {
this.delay = delay
this
}
}
调用时:
new SubBuilder().retryLimit(3).delay(60000)
一点儿毛病都么有。
Kotlin 有这个特性吗?并没有。
3. Kotlin 的解法
Kotlin 倒也不是没有办法解决这个问题,用下泛型就好了:
abstract class EventBuilder<T : EventBuilder<T>>() {
protected var retryLimit = 3
fun retryLimit(retryLimit: Int): T {
this.retryLimit = retryLimit
return this as T
}
abstract fun build(): PollingEvent
}
这个泛型给父类加了一个泛型参数,这个参数则必须是当前类的子类,那么这样的话我们就可以在返回自身类型的位置返回 T 这个类型了。
子类的改动就很简单了,只需要给父类加一个泛型参数为自己的类型即可:
class DisposableEventBuilder : EventBuilder<DisposableEventBuilder>() {
...
}
其他的什么也不用动,这时候我们的链式调用就没啥问题了:
DisposableEventBuilder().retryLimit(3)
.delay(60_000) // OK!!
.build()
这一点上 Kotlin 和 Java 其实是一致的,所以你也可以用 Java 写出类似的代码:
abstract class SuperBuilder<T extends SuperBuilder<T>> {
private int retryLimit = 0;
T retryLimit(int retryLimit) {
this.retryLimit = retryLimit;
return (T) this;
}
}
class SubBuilder extends SuperBuilder<SubBuilder> {
private long delay = 0;
SuperBuilder delay(long delay) {
this.delay = delay;
return this;
}
}
好了,今天就先这样~~
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- python – 如何子类化大pandasDataFrame?
- 从python中的父类文件调用子类方法
- golang 父类调用子类方法、继承多态的实现方式
- ios – 在哪里为子类的uitableviewcell创建自动布局约束?
- C#中子类对基类方法的继承、重写和隐藏
- 如何用 SQL 中的循环查询无限级分类的所有子类
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
码出高效:Java开发手册
杨冠宝、高海慧 / 电子工业出版社 / 2018-10 / 99.00元
《码出高效:Java 开发手册》源于影响了全球250万名开发工程师的《阿里巴巴Java开发手册》,作者静心沉淀,对Java规约的来龙去脉进行了全面而彻底的内容梳理。《码出高效:Java 开发手册》以实战为中心,以新颖的角度全面阐述面向对象理论,逐步深入地探索怎样成为一位优秀开发工程师。比如:如何驾轻就熟地使用各类集合框架;如何得心应手地处理高并发多线程问题;如何顺其自然地写出可读性强、可维护性好的......一起来看看 《码出高效:Java开发手册》 这本书的介绍吧!