Я пытаюсь создать систему, в которой реализации протокола (или абстрактного класса) отвечают минимальным требованиям этого протокола, но все еще имеют доступ к уникальной функциональности, которая поставляется с предоставленным решением. Позвольте мне проиллюстрировать это на примере:
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()
}
}
На данный момент я не совсем уверен, не вижу ли я, как это сделать, или это невозможно. Хотя кажется, что это возможно, и мне интересно, сможет ли кто-нибудь из вас указать мне правильное направление, как решить эту проблему.
Или, может быть, даже не имеет смысла то, что я пытаюсь сделать, но даже то, что я хотел бы услышать, поскольку это имеет смысл для установки, которую я представляю.
Заранее спасибо.
Редактировать после первого ответа:
Я намерен получить доступ к фавориту за пределами стадии строительства.
Превратил изменчивый любимый Food в val, так как он лучше соответствует цели.