【问题标题】:Is there a way to override an abstract property with a subtype of the declared type?有没有办法用声明类型的子类型覆盖抽象属性?
【发布时间】:2023-03-20 17:27:01
【问题描述】:

考虑下面的例子:我有一个Animal的抽象类,每个动物都有一张嘴,但是因为每个动物的嘴都不一样,所以嘴类也是抽象的:

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() 不起作用。

我怎样才能确保狗只有狗嘴(和其他狗的身体部位)?

【问题讨论】:

    标签: kotlin polymorphism abstract-class


    【解决方案1】:

    herehere 解决了类似的问题。 解决方案是使用泛型参数:

    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() 因类型不匹配而失败。

    随着身体部位的增多,需要添加额外的泛型:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多