0
votes

I am learning Scala from Martin Odersky's book "Programming in Scala". In his "Packages and Imports" Chapter there is an example that Martin has in which he is demonstrating how import clauses work. To test my understanding of import clauses in Scala, I created a source file called Vegetable.scala in Eclipse under the Scala perspective.This code is identical to Martin's code, except that I changed the name of the trait from Fruit to Vegetable and the name of the object from Fruits to Vegetables).Shown below is the code for 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)
}

These are my findings: Eclipse does not want to compile this code. It says: "object creation impossible, since: value color in trait Vegetable of type java.awt.Color is not defined value name in trait Vegetable of type String is not defined"

What I hope to accomplish from this code is to understand why this error occurs. How can I make Vegetable available to object Asparagus, Shallot and Cauliflower? My rather (naive) understanding at this point is that since Vegetable and Vegetables occur in the same package and in the same source file, trait Vegetable should be visible to object Asparagus (which extends Vegetable) for example.

Is there something specific about a trait that I need to know before I even use a trait in this manner?

3

3 Answers

5
votes

You are missing the implementation of your objects. This should work:

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 declarations without a value are similar to abstract methods in Java in that they need an 'implementation' i.e. a value.

2
votes

The problem is not one of visibility - it does not compile because Asparagus etc do not provide values for the fields that extends Vegetable requires them to. Each of those objects that you want to extends Vegetable must supply a name and color value.

The following compiles just fine:

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

object Vegetables {
    object Asparagus extends Vegetable {
        val name = "Asparagus"
        val color = "Green"
    }
}
2
votes

As the error indicates, you haven't provided any values for the name or color variables defined in your trait.

You could either provide a default value, like:

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

However that would produce the same value for each object unless you override it. To define for each object, you'd need to do something like:

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