Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error : class Animal needs to be abstract, since: it has 5 unimplemented members

Tags:

scala

In below code I receive this error :

class Animal needs to be abstract, since: it has 5 unimplemented members. /** As seen from class Animal, the 
 missing signatures are as follows. * For convenience, these are usable as stub implementations. */ def 
 favFood_=(x$1: Double): Unit = ??? def flyingType_=(x$1: scala.designpatterns.Strategy.Flys): Unit = ??? def 
 name_=(x$1: String): Unit = ??? def sound_=(x$1: String): Unit = ??? def speed_=(x$1: Double): Unit = ???

If I initialize all of the instance variables of class Animal to _ then the code compiles correctly. What does these error mean ?

package scala.designpatterns

/**
 *
 * Decoupling
 * Encapsulating the concept or behaviour that varies, in this case the ability to fly
 *
 * Composition
 * Instead of inheriting an ability through inheritence the class is composed with objects with the right abilit built in
 * Composition allows to change the capabilites of objects at runtime
 */
object Strategy {

  def main(args: Array[String]) {

    var sparky = new Dog
    var tweety = new Bird

    println("Dog : " + sparky.tryToFly)
    println("Bird : " + tweety.tryToFly)
  }

  trait Flys {
    def fly: String
  }

  class ItFlys extends Flys {

    def fly: String = {
      "Flying High"
    }
  }

  class CantFly extends Flys {

    def fly: String = {
      "I can't fly"
    }
  }

  class Animal {

    var name: String
    var sound: String
    var speed: Double
    var favFood: Double
    var flyingType: Flys

    def tryToFly: String = {
      this.flyingType.fly
    }

    def setFlyingAbility(newFlyType: Flys) = {
      flyingType = newFlyType
    }

    def setSound(newSound: String) = {
      sound = newSound
    }

    def setSpeed(newSpeed: Double) = {
      speed = newSpeed
    }

  }

  class Dog extends Animal {

    def digHole = {
      println("Dug a hole!")
    }

    setSound("Bark")

    //Sets the fly trait polymorphically
    flyingType = new CantFly

  }

  class Bird extends Animal {

    setSound("Tweet")

    //Sets the fly trait polymorphically
    flyingType = new ItFlys
  }

}
like image 492
blue-sky Avatar asked Aug 26 '13 21:08

blue-sky


1 Answers

You must initialize variables. If you don't, Scala assumes you're writing an abstract class and a subclass will fill in the initialization. (The compiler will tell you so if you have just a single uninitialized variable.)

Writing = _ makes Scala fill in the default values.

The point is to make you think about what happens when someone (e.g. you, after you forget that you need to set things first) calls something that uses e.g. the sound without it having been set.

(In general you should at least think carefully about whether this is the right way to structure your code; many fields that require initialization before usage is safe, without any mechanism to enforce initialization, is asking for problems.)

like image 115
Rex Kerr Avatar answered Oct 25 '22 00:10

Rex Kerr