Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Traits in Scala an Interface or an Abstract Class?

Tags:

scala

traits

I have read over the internet that Traits in Scala are

interfaces that can provide concrete members

this means, traits are interface and we may provide body to methods in interface. I have a simple query here, if that is possible than why my below code shows error:

Error:(6, 8) object Car inherits conflicting members: method startEngine in trait Vehical of type => Unit and method startEngine in trait Motor of type => Unit (Note: this can be resolved by declaring an override in object Car.) object Car extends Vehical with Motor {

trait Vehical {
  def startEngine : Unit = {
    println("Vehical Start")
  }
  def stopEngine
}

trait Motor {
  def startEngine : Unit = {
    println("Motor Start")
  }
  def stopEngine
}

object Car extends Vehical with Motor {

  override def stopEngine : Unit = {
    println("Stop Engine")
  }

  def main(args: Array[String]): Unit = {
    Car.startEngine
    Car.stopEngine
  }
}

Being a java developer I would have not provided body inside interface but scala traits allowed this. If traits are not interface then I'll consider them as an abstract class, that means no interface allowed in scala.

Also please let me know how to resolve this ambiguity problem. How can I use my startEngine method in child class if the same method is available in multiple traits.

like image 847
Pardeep Sharma Avatar asked Sep 11 '17 14:09

Pardeep Sharma


People also ask

Is trait an abstract class Scala?

It contains both abstract and non-abstract methods and cannot support multiple inheritances. Like a class, Traits can have methods(both abstract and non-abstract), and fields as its members. Traits are just like interfaces in Java.

Is trait in Scala interface?

Traits are like interfaces in Java. But they are more powerful than the interface in Java because in the traits you are allowed to implement the members. Traits can have methods(both abstract and non-abstract), and fields as its members.

Is trait same as abstract class?

No. Trait supports multiple inheritance. Abstract Class supports single inheritance only. Trait can be added to an object instance.

Is trait a class in Scala?

Introduction. A Trait is a concept pre-dominantly used in object-oriented programming, which can extend the functionality of a class using a set of methods. Traits are similar in spirit to interfaces in Java programming language. Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters.


1 Answers

Being a java developer I would have not provided body inside interface but scala traits allowed this

A trait in Scala provides means of defining a default implementation, and so does Java starting version 8. In Scala, they are primarily used as mixins.

In regards to the compilation error, this arises from the fact that you have declared both Vehicle and Motor with a startEngine method, and that creates an ambiguity from the compilers point of view, since you're mixing in both implementations. To overcome this, you need to explicitly override the method in the implementing class/trait:

override def startEngine: Unit = super.startEngine

One important thing to note is that super here is referring to the last trait in the mixin chain which supplies a startEngine method, in this case Motor. This means that you'll see:

Motor Start
Stop Engine

Which I'd argue is not what you want.

What can be done is to require Vehicle to have a mixed in Motor implementation using self types:

trait Vehicle {
  self: Motor =>

  def startEngine: Unit = {
    println("Vehicle Start")
    startMotor
  }

  def stopEngine: Unit = {
    println("Stopping Engine")
    stopMotor
  }
}

And define your Motor methods in terms of motor only:

trait Motor {
  def startMotor: Unit = {
    println("Motor Start")
  }

  def stopMotor: Unit = {
    println("Stop Motor")
  }
}

And then you mixin everything:

object Car extends Vehicle with Motor

And call:

def main(args: Array[String]): Unit = {
  Car.startEngine
  Car.stopEngine
}

And you get:

Vehicle Start
Motor Start
Stopping Engine
Stop Motor
like image 60
Yuval Itzchakov Avatar answered Oct 08 '22 00:10

Yuval Itzchakov