2013-11-19 1 views
3

Я просто собираюсь через абстрактного типа в 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 = [email protected] 

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) 

Каковы эти ошибки?

Почему я не могу передать new Grass к методу eat в качестве аргумента, и когда я создаю объект как

scala> val c=new Cow 
c: Cow = [email protected] 


scala> c.eat(new Grass) 

Не могли бы вы дать мне некоторое представление об этом?

ответ

3

При назначении bessy вы базовый тип экземпляра Cow к Anmial:

val bessy: Animal = new Cow 

Так что с статической точки зрения, bessy является Animal и поэтому bessy.SuitableFood аннотации. Теперь к ошибкам:

  1. Вы не можете создать объект абстрактного типа с new.
  2. bessy.SuitableFood пытается получить доступ к значению балки SuitableFood (т.е. Защита/знач)
  3. Поскольку bessy является «только» Animal, вы не знаете (статический), если он может съесть Grass.

Что вы можете сделать, это добавить метод к Animal, что позволяет создавать продукты питания:

abstract class Animal { 
    type SuitableFood <: Food 
    def eat(food: SuitableFood) 
    def makeFood(): SuitableFood 
} 

и реализации:

class Cow extends Animal { 
    type SuitableFood = Grass 
    override def eat(food: Grass) {} 
    override def makeFood() = new Grass() 
} 

Теперь вы можете позвонить (на любом Animal) :

bessy.eat(bessy.makeFood()) 
+0

+1 У меня был почти точно такой же ответ. Удаление с первого раза. – drstevens