What is the difference between following two?
1#
trait B extends A {
}
2#
trait B { self: A =>
}
where A
is an abstract class.
>> EDIT:
Please explain with respect to the following example of Duck
s with pluggable flying and quacking behaviors:
abstract class Duck {
def fly(): Unit
def quack(): Unit
def swim() {
println("Woodoowoodoowoodoo...")
}
}
trait FlyingWithWings extends Duck {
override def fly() {
println("Me can fliez! :D")
}
}
trait FlyingNoWay { self: Duck =>
d开发者_开发百科ef fly() {
println("Me cannot fliez! :(")
}
}
trait Quack extends Duck {
override def quack() {
println("Quack! Quack!")
}
}
trait MuteQuack { self: Duck =>
def quack() {
println("<< Silence >>")
}
}
class MallardDuck extends Duck with FlyingWithWings with MuteQuack
object Main {
def main(args: Array[String]) {
val duck = new MallardDuck
duck.fly()
duck.quack()
}
}
Output:
Me can fliez! :D
<< Silence >>
In the second case B can't be used in places where an A is expected, it's just designed to be "attached" to a certain A. So for instance in the first case A could be abstract and B could implement the missing methods, making it an instantiable type. This isn't possible in the second case, you need a "complete A", and only then you add some functionality.
So you could think of a "fits in a ..." relation instead of a "is a ..." relation.
In the first example B
is a specialization of A
. The second means that the trait B
must always be mixed into something that is, or is a subtype of, A
(which can be a class, trait or any other type).
精彩评论