scala> class A
defined class A
scala> trait T extends A { val t = 1 }
defined trait T
//why can I do this?
scala> class B extends T
defined class B
scala> new B
res0: B = B@2e9c76
scala> res0.t
res1: Int = 1
I thought that when you write trait T extends A
, it makes it so you can only put trait T
on a class that is a subclass of A
. Why can I put it on B
, then? Is this only for when you mix it in? Why is this not possible when declaring the class?
"it makes it so you can only put trait T on a class that is a subclass of A"
The feature you want is a self-type annotation. See also Daniel Sobral's answer to this question : What is the difference between self-types and trait subclasses? --> look for the links to dependancy-injection and cake-pattern.
trait A { def t: Int }
trait B {
this: A => // requires that a concrete implementation mixes in from A
def t2: Int = t // ...and therefore we can safely access t from A
}
// strangely this doesn't work (why??)
def test(b: B): Int = b.t
// however this does
def test2(b: B): Int = b.t2
// this doesn't work (as expected)
class C extends B
// and this conforms to the self-type
class D extends B with A { def t = 1 }
You're simply confused about what a trait is. Saying class B extends T
simply means that you're "mixing in" the functionality of the trait to the class definition of B. So, everything defined in T or it's parent classes and traits, is available in B.
What you can't do is:
scala> class A2
defined class A2
scala> class B extends A2 with T
<console>:8: error: illegal inheritance; superclass A2
is not a subclass of the superclass A
of the mixin trait T
class B extends A2 with T
^
Actually, writing class B extends T
is the same as writing class B extends A with T
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.