There are two things to compate with traits (1) Multiple Inheritance (2) Mixin
Python supports limited Multiple Inheritance, oftenly multiple inheritance is criticized for many reasons.
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.
<statement-N>
Above examples shows multiple inheritance thingy in Python. But why its bad? Semantic ambiguity, Not being able to explicitly inherit multiple times from a single class and Order of inheritance changing class semantics. In general Multiple inheritance may produce wrong output in some cases. That's why Mixin is invented?
Some says Multiple Inheritence is an Evil, While some says it is not, IMO it is upto you how you do it. In compex circumstances it may turn out to be an evil. Mix-in is very similar to Abstract Base Classes, Mixin class is to be inherited by subclass and it donot get instantized.
>>> class MixCounter(object):
... count_from = 0
... def next(self):
... return self.count_from + 1
...
>>> class CountFrom10(MixCounter):
... count_from = 10
...
>>> CountFrom10().next()
11
In Scala you'd do something like
scala> abstract class MixCounter {
| val count_from = 0
| def next():Int = { return count_from+1 }
| }
defined class MixCounter
scala> class CountFrom10 extends MixCounter {
| override val count_from = 10
| }
defined class CountFrom10
scala> val a= new CountFrom10()
a: CountFrom10 = CountFrom10@1da366c
scala> a.next()
res4: Int = 11
But Scala also offer's traits. Traits are very similar to Mixin or Abstract classes but they may also include definations for class methods. In principal traits doesnt mix classes e.g if you run trait version of above example
scala> trait CountNumber {
| val count_from = 0
| def next():Int = { return count_from + 1 }
| }
defined trait CountNumber
scala> class CountFrom10 extends CountNumber {
| override val count_from = 10
| }
defined class CountFrom10
scala> val a = new CountFrom10()
a: CountFrom10 = CountFrom10@18590c5
scala> a.next()
So what you think what should be the result? 11 or 1? No it's not 11 .. it's 1
res6: Int = 1
So, you see traits is very different from mix-in though it's quite resemble. It looks that mix-in is actually mix-in one class but trait does it bidrectionally. Now consider following example.
scala> trait EvenOddTeller {
| def is_even(x: Int): Boolean
| def is_odd(x: Int): Boolean = !is_even(x)
| }
defined trait EvenOddTeller
scala> class Number extends EvenOddTeller {
| def is_even(num:Int):Boolean = { return num%2==0 }
| }
scala> val a= new Number()
a: Number = Number@1d15a18
scala> a.is_even(10)
res7: Boolean = true
scala> a.is_odd(10)
res8: Boolean = false
scala> a.is_odd(11)
res9: Boolean = true
In scala traits you have to define all methods which are just declated in trait in your subclass. In short Scala Traits provides a safe mix-in mechanism with full re-usability.
scala> trait RestResource {
| def response():String
| def json():String = { return "{rsp:%d}".format(response) }
| def xml():String = { return "<rsp>%s</rsp>".format(response) }
| }
defined trait RestResource
scala> class Resource(val inp:String) extends RestResource {
| val input: String = inp
| def response() = { return input }
| }
scala> new Resource("Hello World") xml
res15: String = <rsp>Hello World</rsp>
There are many place in development traits are very useful.