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.
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.
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.
No. Trait supports multiple inheritance. Abstract Class supports single inheritance only. Trait can be added to an object instance.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With