1
当我试图在斯卡拉在马丁·奥德斯基的编程抽象类型的动物/食品例,抽象类型涉及Scala时没有动态绑定?
class Food
abstract class Animal {
type SuitableFood <: Food
def eat(food:SuitableFood)
}
class Grass extends Food
class Cow extends Animal {
type SuitableFood=Grass
override def eat(food:SuitableFood) {}
}
val bessy:Animal = new Cow
bessy.eat(new Grass)
我得到了以下错误:
scala> <console>:13: error: type mismatch;
found : Grass
required: bessy.SuitableFood
bessy.eat(new Grass)
^
原例如通过马丁bessy.eat(new Fish)
,这肯定会失败,但我没想到它也会因为Grass
而失败。通过让bessy
为Cow
而不是Animal
:val bessy:Cow = new Cow
可以避免上述错误。
这是否意味着动态绑定在这里不起作用?
编辑: 简单的动态进行定期继承Scala中绑定:
abstract class Parent {
def sig:String = "Parent"
}
class Child extends Parent {
override def sig:String = "Child"
}
而且我有这个,在x:Parent
给儿童还有:
scala> new Child().sig
res1: String = Child
val x:Parent = new Child()
x: Parent = [email protected]
x.sig
res2: String = Child
那么,我采取的动态绑定概念是错误的? Java中的'List'具有'LinkedList'和'ArrayList',所以当你在一个'List'上调用一个'xs.get(idx)'时,当它是'ArrayList'的实现时就会得到'ArrayList'版本。我没有想到Scala会偏离这一点。 – lcn
@lcn - 类型必须匹配。您的“简单”示例对“Parent.sig”和“Child.sig”具有相同的类型签名。继承(C++中的“动态绑定”类型)工作得很好,但你必须服从你给出的类型。 –
所以你的意思是当涉及抽象类型时,'eat'方法会有*不同的签名,因此是不同的方法?我明白这适合于抽象类型的目的,但应该记录下这里有* NO *动态绑定。 – lcn