内容简介:一看题目,有点儿晕。看个例子马上就明白了:我们有这么一个类,一看就是要写 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 中的循环查询无限级分类的所有子类
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
即将到来的场景时代
罗伯特•斯考伯、谢尔•伊斯雷尔 / 赵乾坤 周宝曜 / 北京联合出版公司 / 2014-5-1 / 42
科技大神、全球科技创新领域最知名记者 罗伯特·斯考伯:“技术越了解你,就会为你提供越多好处!” 互联网的炒作点一个一个不停出现,大数据、3D打印、O2O等,无不宣扬要颠覆商业模式。但是,互联网进入移动时代,接下来到底会发生什么?移动互联网时代真正带来哪些改变?这具体会怎样影响我们每一个人的生活?商业真的会被颠覆?目前为止没有一本书给出答案。 《即将到来的场景时代》不是就一个炒作点大加谈......一起来看看 《即将到来的场景时代》 这本书的介绍吧!