abstract type in scala

时光总嘲笑我的痴心妄想 提交于 2019-12-10 09:34:55

问题


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?


回答1:


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:

  1. You cannot create an object of an abstract type with new.
  2. bessy.SuitableFood tries to access the value-member SuitableFood (i.e. def/val)
  3. Since 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())


来源:https://stackoverflow.com/questions/20070998/abstract-type-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!