如何使对象具有特征

时间:2012-08-22 17:02:49

标签: eclipse scala

我正在从Martin Odersky的书“Scala编程”中学习Scala。在他的“包装和进口”章节中,有一个例子,马丁在其中展示了进口条款的工作原理。为了测试我对Scala中import子句的理解,我在Scala透视图下在Eclipse中创建了一个名为Vegetable.scala的源文件。这段代码与Martin的代码完全相同,只不过我将特征的名称从Fruit更改为Vegetable并且名称从水果到蔬菜的对象)。下面是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中的值未定义特征中的值名称未定义字符串类型的蔬菜”

我希望通过此代码实现的目的是了解发生此错误的原因。如何使用蔬菜来对象芦笋,青葱和花椰菜?在这一点上,我相当(天真)的理解是,由于蔬菜和蔬菜出现在同一个包装和相同的源文件中,因此对象芦笋(延伸蔬菜)应该可以看到特性蔬菜。

在我以这种方式使用特征之前,我是否需要了解一些特定的特征?

3 个答案:

答案 0 :(得分:4)

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

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中的抽象方法,因为它们需要一个“实现”,即一个值。

答案 1 :(得分:2)

问题不在于可见性 - 它不能编译,因为Asparagus等不为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"
    }
}

答案 2 :(得分:2)

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

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

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

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

object Asparagus extends Vegetable { 
  val name = "Asparagus"
  val color = Color.GREEN
}