以下是关于“动物吃食物”的故事,还有一只猫吃鱼 .
class Food
abstract class Animal {
type F
def eat(food: F)
}
class Fish extends Food
class Cat extends Animal {
type F = Fish
def eat(fish: F) {
println("eat " + fish.getClass.getSimpleName)
}
}
(new Cat).eat(new Fish) //eat Fish
val animal: Animal = new Cat
animal.eat(new Fish) //error: type mismatch
现在我已经使用了抽象类型的成员(或类型参数),我 lose runtime polymorphism
(在最后一行) . (使用基类型Animal键入任意子类型并运行没有问题 . )
否则,我可以从Animal中删除type参数并在Cat中键入check:
abstract class Animal {
def eat(food: Food)
}
class Cat extends Animal {
def eat(food: Food) {
food match {
case fish: Fish => println("eat" + fish)
case _ => throw new IllegalArgumentException("I only eat fish")
}
}
}
但我想为他们打字更好 .
那么在使用type-parameter / generic时我可以保留运行时多态性吗?
2 回答
不,你可以用它的子类型替换
Animal
(在这样的上下文中,并不总是!),但反之亦然 . 如果可以,您也可以使用Object
,因为它也是Cat
的基本类型:希望你明白为什么这不应该编译 .
或者你可以用另一种方式:应该
编译?如果您认为答案是"yes",请考虑
makeAnAnimal()
可以返回Cow
.我不确定这是否是最佳方法,但似乎有效 . 您可以允许将任何类型的食物传递给冒着类别施放异常的动物,如果发生则处理它 .