I am just going through abstract type in Scala
and I got an error
The example I was trying:
scala> class Food
abstract class Animal {
type SuitableFood <: Food
def eat(food: SuitableFood)
}
defined class Food
defined class Animal
scala> class Grass extends Food
class Cow extends Animal {
type SuitableFood = Grass
override def eat(food: Grass) {}
}
defined class Grass
defined class Cow
scala> class Fish extends Food
defined class Fish
scala> val bessy: Animal = new Cow
bessy: Animal = Cow@5c404da8
scala> bessy.eat(new bessy.SuitableFood)
<console>:13: error: class type required but bessy.SuitableFood found
bessy.eat(new bessy.SuitableFood)
^
scala> bessy.eat(bessy.SuitableFood)
<console>:13: error: value SuitableFood is not a member of Animal
bessy.eat(bessy.SuitableFood)
scala> bessy.eat(new Grass)
<console>:13: error: type mismatch;
found : Grass
required: bessy.SuitableFood
bessy.eat(new Grass)
What are these errors?
Why can't I pass new Grass
to the eat
method as an argument, and when I create an object like
scala> val c=new Cow
c: Cow = Cow@645dd660
scala> c.eat(new Grass)
Could you give me some idea about this?
When you assign bessy
, you upcast the Cow
instance to an Anmial
:
val bessy: Animal = new Cow
So from a static point of view, bessy
is an Animal
and therefore bessy.SuitableFood
abstract. Now to the errors:
new
.bessy.SuitableFood
tries to access the value-member SuitableFood
(i.e. def/val)bessy
is "only" an Animal
, you don't know (statically) if it can eat Grass
.What you can do, is add a method to Animal
that allows you to create food:
abstract class Animal {
type SuitableFood <: Food
def eat(food: SuitableFood)
def makeFood(): SuitableFood
}
And implement:
class Cow extends Animal {
type SuitableFood = Grass
override def eat(food: Grass) {}
override def makeFood() = new Grass()
}
Now you may call (on any Animal
):
bessy.eat(bessy.makeFood())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With