有没有办法用声明类型的子类型覆盖抽象 属性 ?
Is there a way to override an abstract property with a subtype of the declared type?
考虑下面的例子:我有一个Animal的抽象class,每个动物都有嘴,但是因为每个动物的嘴都不一样,所以嘴class也是抽象的:
abstract class Animal {
var numberLegs: Int = 4
var mouth: Mouth? = null
}
abstract class Mouth {
abstract fun makeSound()
}
我现在可以创建 Dog 和 DogMouth:
class Dog: Animal() {
override var mouth: Mouth = DogMouth()
}
class DogMouth: Mouth() {
override fun makeSound() {
println("Bark!")
}
}
但这让我也可以为狗分配其他类型的嘴巴,这是我不想要的,例如:
class CatMouth: Mouth() {
override fun makeSound() {
println("Meow!")
}
}
fun main() {
val dog = Dog()
dog.mouth.makeSound() // will print "Bark!"
dog.mouth = CatMouth() // I don't want this to work
dog.mouth.makeSound() // will print "Meow!"
}
设置override var mouth: DogMouth = DogMouth()
无效。
如何确保狗只有 DogMouths(和其他狗 body 部分)?
解决了类似的问题 here and here。
解决方案是使用通用参数:
abstract class Animal<MouthType: Mouth> {
var numberLegs: Int = 4
abstract var mouth: MouthType
}
class Dog: Animal<DogMouth>() {
override var mouth: DogMouth = DogMouth()
}
这使得 dog.mouth = CatMouth()
因类型不匹配而失败。
需要添加更多 body 部分额外的泛型:
abstract class Animal<MouthType: Mouth, EarType: Ear, TailType: Tail> {
var numberLegs: Int = 4
abstract var mouth: MouthType
abstract var ear: EarType
abstract var tail: TailType
}
考虑下面的例子:我有一个Animal的抽象class,每个动物都有嘴,但是因为每个动物的嘴都不一样,所以嘴class也是抽象的:
abstract class Animal {
var numberLegs: Int = 4
var mouth: Mouth? = null
}
abstract class Mouth {
abstract fun makeSound()
}
我现在可以创建 Dog 和 DogMouth:
class Dog: Animal() {
override var mouth: Mouth = DogMouth()
}
class DogMouth: Mouth() {
override fun makeSound() {
println("Bark!")
}
}
但这让我也可以为狗分配其他类型的嘴巴,这是我不想要的,例如:
class CatMouth: Mouth() {
override fun makeSound() {
println("Meow!")
}
}
fun main() {
val dog = Dog()
dog.mouth.makeSound() // will print "Bark!"
dog.mouth = CatMouth() // I don't want this to work
dog.mouth.makeSound() // will print "Meow!"
}
设置override var mouth: DogMouth = DogMouth()
无效。
如何确保狗只有 DogMouths(和其他狗 body 部分)?
解决了类似的问题 here and here。 解决方案是使用通用参数:
abstract class Animal<MouthType: Mouth> {
var numberLegs: Int = 4
abstract var mouth: MouthType
}
class Dog: Animal<DogMouth>() {
override var mouth: DogMouth = DogMouth()
}
这使得 dog.mouth = CatMouth()
因类型不匹配而失败。
需要添加更多 body 部分额外的泛型:
abstract class Animal<MouthType: Mouth, EarType: Ear, TailType: Tail> {
var numberLegs: Int = 4
abstract var mouth: MouthType
abstract var ear: EarType
abstract var tail: TailType
}