scala 中的抽象类型

Rah*_*ari 5 scala abstract path-dependent-type

我只是通过抽象类型输入Scala,但出现错误

我正在尝试的示例:

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)
Run Code Online (Sandbox Code Playgroud)

这些错误是什么?

为什么我不能作为参数传递new Grasseat方法,当我创建一个对象时

scala> val c=new Cow
c: Cow = Cow@645dd660


scala> c.eat(new Grass)
Run Code Online (Sandbox Code Playgroud)

你能给我一些关于这个的想法吗?

gzm*_*zm0 5

当您分配时bessy,您将Cow实例向上转换为Anmial

val bessy: Animal = new Cow
Run Code Online (Sandbox Code Playgroud)

所以从静态的角度来看,bessy是一个Animal,因此是bessy.SuitableFood抽象的。现在到错误:

  1. 不能用 来创建抽象类型的对象new
  2. bessy.SuitableFood尝试访问值成员SuitableFood(即 def/val)
  3. 由于bessy是“仅” an Animal,因此您(静态地)不知道它是否可以吃Grass

您可以做的是添加一个方法Animal来创建食物:

abstract class Animal {
  type SuitableFood <: Food
  def eat(food: SuitableFood)
  def makeFood(): SuitableFood
}
Run Code Online (Sandbox Code Playgroud)

并实施:

class Cow extends Animal {
  type SuitableFood = Grass
  override def eat(food: Grass) {}
  override def makeFood() = new Grass()
}
Run Code Online (Sandbox Code Playgroud)

现在你可以调用(在任何Animal):

bessy.eat(bessy.makeFood())
Run Code Online (Sandbox Code Playgroud)