Kotlin 如何使用超类型参数重写方法
我有一个像这样的Kotlin 如何使用超类型参数重写方法,kotlin,inheritance,overriding,Kotlin,Inheritance,Overriding,我有一个像这样的水果课程 open class Fruit(var taste: String) { open fun consume(from: Fruit) { taste = from.taste } } class Apple( var color: String, taste: String ): Fruit(taste) { // caution: method overrides nothing override
水果课程
open class Fruit(var taste: String) {
open fun consume(from: Fruit) {
taste = from.taste
}
}
class Apple(
var color: String,
taste: String
): Fruit(taste) {
// caution: method overrides nothing
override fun consume(from: Apple) {
super.consume(from)
color = from.color
}
}
我有一个Apple
类,它像这样扩展了Fruit
类
open class Fruit(var taste: String) {
open fun consume(from: Fruit) {
taste = from.taste
}
}
class Apple(
var color: String,
taste: String
): Fruit(taste) {
// caution: method overrides nothing
override fun consume(from: Apple) {
super.consume(from)
color = from.color
}
}
这是我的使用代码:
val fruit: Fruit = Apple(color = "green", taste = "sweet")
val badFruit = Apple(
color = anyOf("red", "blue", "golden"),
taste = anyOf("sour+", "sweet+", "chilli+")
)
fruit.consume(from = badFruit)
println("BadFruit: $badFruit")
println("InfectedFruit: $fruit")
问题:
我无法在Apple
类中重写以下方法:
override fun consume(from: Apple) {
super.consume(from)
color = from.color
}
为了正确重写这个方法,我需要传入一个Fruit类的实例(就像超级方法一样)。如果我这样做,我将始终必须检查Fruit
实例是否实际上是Apple
实例。但是,它不应该只与前者一起工作,因为苹果扩展了水果吗
我如何实现这样的功能,当我在水果:水果=苹果(…)
上调用消费()
时,它实际上调用了苹果消费()
方法
做这件事的好方法是什么?虽然在评论中提出了技术替代方案,但我想补充另一个观点。我们在这里看到的是一个类设计问题,当试图将继承用于真正的泛化/专门化关系之外的任何事物时,会出现这个问题
该示例声明:
每个水果
必须能够消费另一个水果
苹果是一种水果
那么这个想法是:
苹果
不得食用任何种类的水果
,只能食用苹果
虽然在评论中提出了技术替代方案,但我想补充另一个观点。我们在这里看到的是一个类设计问题,当试图将继承用于真正的泛化/专门化关系之外的任何事物时,会出现这个问题
该示例声明:
- 每个
水果
必须能够消费另一个水果
- 苹果是一种水果
那么这个想法是:
苹果
不得食用任何种类的水果
,只能食用苹果
。这似乎是XY问题的一个例子,在这里合成可以代替“静态固有”。你可能想看看我对一个类似问题的回答。另外,请提供有关您试图解决的实际问题的更多信息。如果您希望Apple类仅使用Apple,则只需将Fruit类设置为泛型逆变参数。或者,如果想要同时接受这两个属性,那么只需接受Fruit并执行if检查,如果实例是Apple,如果是,则更改color属性。@AnimeshSahu我想避免使用泛型。但是,这似乎是公平的,这将需要“生产者输入,消费者输出”之类的实现。这似乎是XY问题的一个例子,在这里,合成可以有帮助,而不是“静态固有”。你可能想看看我对一个类似问题的回答。另外,请提供有关您试图解决的实际问题的更多信息。如果您希望Apple类仅使用Apple,则只需将Fruit类设置为泛型逆变参数。或者,如果想要同时接受这两个属性,那么只需接受Fruit并执行if检查,如果实例是Apple,如果是,则更改color属性。@AnimeshSahu我想避免使用泛型。但是,这似乎是公平的,这将需要“生产者进来,消费者出去”之类的实现。例如,假设我有一个果核。它包含大小和重量等基本属性。我创建了CoreFruit的两个子类;叫做酸果和甜果。现在,如果SourFruit在CoreFruit类型的列表中,我打算手动创建底层SourFruit的副本,比如sourFruitButTypedAsFruit.copy()
;我如何确保这将复制SourFruit和CoreFruit的属性consume()
类似,但它将一个水果写入另一个水果。你能举个例子吗?请看上面答案中添加的通过引用基类复制派生类一节。我同意你的继承建议。例如,假设我有一个果核。它包含大小和重量等基本属性。我创建了CoreFruit的两个子类;叫做酸果和甜果。现在,如果SourFruit在CoreFruit类型的列表中,我打算手动创建底层SourFruit的副本,比如sourFruitButTypedAsFruit.copy()
;我如何确保这将复制SourFruit和CoreFruit的属性consume()
类似,但它将一个水果写入另一个水果。你能举个例子吗?请看上面答案中增加的通过引用基类复制派生类一节。