0

我正在从 Martin Odersky 的“Scala 编程”一书中学习 Scala。在他的“包和导入”一章中,Martin 举了一个例子,他在其中演示了导入子句的工作原理。为了测试我对 Scala 中 import 子句的理解,我在 Scala 透视图下的 Eclipse 中创建了一个名为 Vegetable.scala 的源文件。此代码与 Martin 的代码相同,只是我将 trait 的名称从 Fruit 更改为 Vegetable 以及名称从水果到蔬菜的对象)。下面是蔬菜.scala的代码

package com.att.scala
import java.awt.Color

trait Vegetable {
  val name: String
  val color: Color
}

object Vegetables {
   object Asparagus extends Vegetable { } 
   object Shallot extends Vegetable { }
   object Cauliflower extends Vegetable { }
   object Spinach extends Vegetable { }
   val veggiePlatter = List(Asparagus, Shallot)
}

这些是我的发现: Eclipse 不想编译这段代码。它说:“不可能创建对象,因为:java.awt.Color 类型的特征蔬菜中的值颜色未定义字符串类型的特征蔬菜中的值名称未定义”

我希望从这段代码中完成的是理解为什么会发生这个错误。我怎样才能使蔬菜可用于反对芦笋、青葱和花椰菜?在这一点上,我相当(天真)的理解是,由于蔬菜和蔬菜出现在同一个包和同一个源文件中,因此特性蔬菜应该对对象 Asparagus (扩展蔬菜)是可见的。

在我以这种方式使用特征之前,我是否需要了解某个特征的具体内容?

4

3 回答 3

5

您缺少对象的实现。这应该有效:

package com.att.scala
import java.awt.Color

trait Vegetable {
  val name: String
  val color: Color
}

object Vegetables {
   object Asparagus extends Vegetable { 
       name = "Asparagus"
       color = new Color(255,255,255)
   } 
   //...
}

没有值的 val 声明类似于 Java 中的抽象方法,因为它们需要一个“实现”,即一个值。

于 2012-08-22T17:12:03.587 回答
2

问题不在于可见性 - 它无法编译,因为Asparagusetc 没有为extends Vegetable需要它们的字段提供值。您想要的每个对象都extends Vegetable必须提供一个namecolor值。

以下编译得很好:

trait Vegetable {
    val name: String
    val color: String
}

object Vegetables {
    object Asparagus extends Vegetable {
        val name = "Asparagus"
        val color = "Green"
    }
}
于 2012-08-22T17:13:02.900 回答
2

如错误所示,您没有为特征中定义的名称或颜色变量提供任何值。

您可以提供默认值,例如:

trait Vegetable {
  val name: String = "Some Vegetable"
  val color: Color = Color.GREEN
}

但是,除非您覆盖它,否则这将为每个对象产生相同的值。要为每个对象定义,您需要执行以下操作:

object Asparagus extends Vegetable { 
  val name = "Asparagus"
  val color = Color.GREEN
} 
于 2012-08-22T17:13:32.863 回答