ent*_*ave 3 generics types scala abstract-type
在Odersky等人的Scala编程中有一个关于抽象类型的简单例子,但它似乎没有遵循它的逻辑结论[现在编辑使我的确切代码]:
class Food
class Grass extends Food
class FishFood extends Food
abstract class Animal {
type Feed <: Food
def eat(food: Feed)
}
class Cow extends Animal {
type Feed = Grass
override def eat(food: Grass) = {}
}
class Test extends App {
val cow: Animal = new Cow
cow.eat(new FishFood)
cow.eat(new Grass)
}
Run Code Online (Sandbox Code Playgroud)
他们解释说这会阻止我做(如上所述):
val cow: Animal = new Cow
cow.eat(new FishFood)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但下一个自然步骤似乎也不起作用:
cow.eat(new Grass)
Run Code Online (Sandbox Code Playgroud)
我收到编译错误:
type mistmatch;
found : Grass
required: Test.this.cow.Feed
cow.eat(new Grass)
^
Run Code Online (Sandbox Code Playgroud)
但是牛.饲料是草,所以为什么这不起作用?
这里的问题是你的val cow被输入Animal而不是Cow,所以编译器知道的是它的eat方法需要一些特定的子类型Food,但它不知道哪个,特别是它无法证明该类型等于Grass.
通过询问它的eta扩展,你可以看到它对方法类型的不同(从Animal查看中看到的Cow).
scala> val cow: Animal = new Cow
cow: Animal = Cow@13c02dc4
scala> cow.eat _
res12: cow.Feed => Unit = <function1>
scala> cow.asInstanceOf[Cow].eat _
res13: Grass => Unit = <function1>
Run Code Online (Sandbox Code Playgroud)
您会注意到,在第二种更精确类型的情况下,编译器将该方法视为采用类型的参数Grass而不是抽象类型cow.Feed.