No dynamic binding when abstract type involved in Scala?

402 views Asked by At

When I was trying the Animal/Food example for abstract types in Martin Odersky's Programming in 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)

I got the following error:

scala> <console>:13: error: type mismatch;
 found   : Grass
 required: bessy.SuitableFood
                  bessy.eat(new Grass)
                            ^

The original example by Martin was bessy.eat(new Fish), which would definitely fail, but I didn't expect it'd fail for Grass as well. The above error can be avoided by letting bessy be Cow instead of Animal: val bessy:Cow = new Cow.

Does this mean dynamic binding doesn't work here?

Edited: Simple dynamic binding for regular inheritance in Scala:

abstract class Parent {
  def sig:String = "Parent"
}
class Child extends Parent {
  override def sig:String = "Child"
}

And I had this, where x:Parent gave Child as well:

scala> new Child().sig
res1: String = Child

val x:Parent = new Child()
x: Parent = Child@3a460b07

x.sig
res2: String = Child
1

There are 1 answers

4
Rex Kerr On BEST ANSWER

Scala is statically typed. An arbitrary animal cannot eat grass, and you have just tried to feed grass to an arbitrary animal. It happens to be a cow, but you have stated (with : Animal) that the compiler may only assume that it is an animal.

If you allow the compiler to know that bessy is a Cow (val bessy = new Cow), then she'll eat grass just fine.