0

我正在尝试创建一个系统,其中协议(或抽象类)的实现满足该协议的最低要求,但仍然可以访问所提供解决方案附带的独特功能。让我用一个例子来说明:

interface Food
interface Animal {
    val favoriteFood: Food
}

class Banana: Food {
    fun peel() {
        print("Banana peeled")
    }
}

class Monkey: Animal {
    override val favoriteFood: Food = Banana()

    init {
        favoriteFood.peel() // Doesn't work as type is Food, not Banana
    }
}

现在要破解这个问题,我一直在研究泛型和具体化函数,但我无法想出以表达方式工作的东西。

我应该注意,我的实现必须满足多个要求。我可以通过在协议上使用泛型来完成这项工作。

interface Animal<T: Food, B: Behaviour>

这会起作用,但是有多个要求它很快看起来很荒谬,我觉得我错过了一些东西。属性的泛型不起作用,除非我在下一个示例中遗漏了一些东西。:

// Protocol
val <T> favoriteFood: <T: Food>
// Implementation (ideally, but wouldn't work like that I guess)
override val favoriteFood: Banana = Banana()

然后我的具体方法看起来也不那么漂亮:

open class Animal {
    // This should ideally be private to prevent incorrect use
    var favoriteFood: Food? = null

    fun registerFavoriteFood(food: Food) {
        favoriteFood = food
    }

    // This probably doesn't even have to be inline+reified
    inline fun <reified  T> getFavoriteFood() : T {
        // Of course we need to validate if favoriteFood matches T 
        return favoriteFood as T
    } 
}

class Monkey: Animal() {
    init {
        registerFavoriteFood(Banana())
        getFavoriteFood<Banana>().peel()
    }
}

在这一点上,我不完全确定我是否不知道该怎么做,或者是否不可能。感觉这是可能的,我想知道你们中是否有人能指出我如何解决它的正确方向。

或者也许我想要做的事情甚至没有意义,但即使是我想听到的,因为它对我设想的设置确实有意义。

提前致谢。

第一次回复后编辑: 我打算在构建阶段之后访问 favoriteFood。将可变的 favoriteFood 变成了一个更符合目标的 val。

4

1 回答 1

1

只要您只是尝试favoriteFood在构建时访问,这还不错:

class Monkey: Animal {
    override var favoriteFood: Food? // no initializer here

    init {
        val food = Banana()
        favoriteFood = food
        food.peel()
    }
}

如果您将自己限制在init部分和其他施工时间操作中,那么您尝试做的事情从根本上被破坏了。

val animal: Animal = Monkey()
animal.favoriteFood = Orange() // favoriteFood is a var, so it's publicly modifiable
animal.something() // can't assume favoriteFood is a Banana!

你可以做成favoriteFood一个val,这会有所帮助。但是您不能favoriteFood从 in 类型的外部进行可变,Food并尝试限制 in 子类型的favoriteFood类型。

于 2019-01-23T22:42:58.870 回答