3

I'm learning Scala and am trying to get a simple enum setup for a project. I've checked a few examples and none seem to fit, all of the examples in the Scala documentation and on StackOverflow are for enums inside objects, not classes. I'm getting an IDE warning that I don't understand. I'm coming from a beginner Java background into Scala, which may be the cause of my confusion.

Here's the code:

class Car(maxSpeed: Integer) {

  // Enums
  object CarType extends Enumeration {
    type CarType = Value
    val PERIPHERAL, COMPUTER, EMPTY = Value
  }
  import CarType._

  // Fields
   val repeated: CarType
}

When I mouse over the class name, I can see this Intellij warning:

Class 'Car' must either be declared abstract or implement abstract member 'typed: Car.this.CarType.CarType' in 'Car'

I'm not sure why it wants me to implement my variable, and the class is not intended to be abstract. I'd like to use Enums similarly to how they are used in Java.

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
sudom82
  • 135
  • 2
  • 12

2 Answers2

7

Move the enumeration outside the class:

// Enums
object CarType extends Enumeration {
  type CarType = Value
  val PERIPHERAL, COMPUTER, EMPTY = Value
}
class Car(maxSpeed: Integer) {
  import CarType._

  // Fields
   val repeated: CarType
}

Or move it to a companion object:

class Car(maxSpeed: Integer) {
  import Car.CarType._

  // Fields
   val repeated: CarType
}

object Car {
  object CarType extends Enumeration {
    type CarType = Value
    val PERIPHERAL, COMPUTER, EMPTY = Value
  }
}

The problem is that things defined inside of a class are scoped to the the instance of that class (unlike some other languages).

That said, I recommend using algebraic data types instead of enums:

sealed trait CarType
object CarType {
  case object Peripheral extends CarType // strange choice of names
  case object Computer extends CarType
  case object Empty extends CarType
}

case class Car(maxSpeed: Int, carType: CarType)

For more info about sealed traits see this SO q&a

Joey Baruch
  • 4,180
  • 6
  • 34
  • 48
Alvaro Carrasco
  • 6,103
  • 16
  • 24
  • You should link to documentation on companion objects: new Scala users probably won't map the static method/singleton concept to companion objects super-readily. – Nathaniel Ford Sep 09 '16 at 01:30
  • Thanks. Your answer helped me best figure out my issue. I'm quite impressed by stackoverflow's response speed, this is my first time using it. and I had a <30 minute response with detail. – sudom82 Sep 09 '16 at 02:05
  • Moving to a companion object didn't work out for me. First, the scalastyle checker complained about the relative ref `import Car.CarType._`. Second, I cannot use the enum outside the `Car` class file. There was some error about expecting the type `CarType.CarType` but the actual type was `CarType.Value`. What worked was the old-fashioned way i.e. I moved the enum definition to its own file. – ruhong Apr 25 '17 at 06:24
0

What you're looking for is a Scala Case Class.

class Car(maxSpeed: Integer)
case class Minivan(maxSpeed: Integer) extends Car(maxSpeed: Integer)
case class Hodrod(maxSpeed: Integer) extends Car(maxSpeed: Integer)
case class Coupe(maxSpeed: Integer) extends Car(maxSpeed: Integer)

Enumerations as they exist in Java aren't really used in Scala. By having a construction like what I have above, you can leverage Scala's powerful pattern matching do something like this:

val unknownCar = getCar() // Some function that gets a car
unknownCar match {
  case Minivan => println("Driving the kids")
  case Hodrod => println("Tearing up the drag")
  case Coupe => println("Riding low")
}

...while still allowing you to treat it as a Car.

Because they are case classes Scala has a lot of things that help you out.

Note the documentation for Enumeration:

Typically these values enumerate all possible forms something can take and provide a lightweight alternative to case classes.

You should really only use it if you aren't planning to use those values for anything else - but even there case classes will generally serve you better.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102