gpt4 book ai didi

inheritance - Kotlin 强制实现类成为另一种类型的父类(super class)型

转载 作者:行者123 更新时间:2023-12-02 12:34:10 29 4
gpt4 key购买 nike

由于在 java/kotlin 中不允许多重继承,因此利用接口(interface)默认方法很有用。举个例子:

abstract class Animal { 
fun beAnimal() {
println("I'm animal!")
}
}
abstract class Mammal : Animal() {
fun produceMilk() {
beAnimal().apply { println("Freesh milk!") }
}
}
abstract class AnimalWithBeak : Animal() {
fun quack() {
beAnimal().apply { println("Quack!") }
}
}
class Platypus : ??? // I want it to both produce milk and quack!

如上所述,不允许多个基类,但我们可以使用接口(interface):

abstract class Animal { fun beAnimal() { println("I'm animal!") } }

interface Mammal {
fun produceMilk() {
(this as Animal).beAnimal().apply { println("Freesh milk!") }
}
}
interface AnimalWithBeak {
fun quack() {
(this as Animal).beAnimal().apply { println("Quack!") }
}
}
class Platypus : Animal(), Mammal, AnimalWithBeak {
fun bePlatypus() {
quack() // ok
produceMilk() // ok
}
}

请注意,我不拥有 Animal 类,但我仍然想继承它,并且能够混合这些实现。上面的例子很简单,但在实际代码中它会非常有用。

问题是,不扩展 Animal 的类可以实现 MammalAnimalWithBeak 接口(interface)。在这种情况下,代码将被破坏,因为 this as Animal 转换将失败。

所以问题 - 是否可以将接口(interface)继承限制为仅对特定类?在这种情况下,应该只允许扩展 Animal 的类实现 MammalAnimalWithBeak 接口(interface)。

可能不存在的抽象语法可能看起来像这样:

interface Mammal where this : Animal

但我怀疑它无效。有什么解决办法吗?

最佳答案

您不能限制接口(interface)可以由哪些类来实现。然而,如果你想避免强制转换,你可以给接口(interface)一个 Animal 类型的属性,实现类必须重写。这至少可以确保实现类有一个可用的 Animal 对象。

abstract class Animal { fun beAnimal() { println("I'm animal!") } }

interface Mammal {
val animal: Animal

fun produceMilk() {
animal.beAnimal().apply { println("Freesh milk!") }
}
}

interface AnimalWithBeak {
val animal: Animal

fun quack() {
animal.beAnimal().apply { println("Quack!") }
}
}

class Platypus : Animal(), Mammal, AnimalWithBeak {
override val animal = this

fun bePlatypus() {
quack() // ok
produceMilk() // ok
}
}

关于inheritance - Kotlin 强制实现类成为另一种类型的父类(super class)型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51494134/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com