0
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?

ryeguy
  • 65,519
  • 58
  • 198
  • 260

3 Answers3

5

"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 }
Community
  • 1
  • 1
0__
  • 66,707
  • 21
  • 171
  • 266
0

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.

Thomas Lockney
  • 2,567
  • 20
  • 13
  • Right, but `trait T extends A` is supposed to only allow you to mixin the trait to class A. It works as intended if you try doing `new B with T` - it won't let you. – ryeguy Mar 22 '11 at 13:17
  • No, `trait T extends A` is *not* supposed to only allow you to mixin the trait to class A. It is adding in the functionality of the class A to the trait T. So T has the functionality (methods and fields) of class A and anything you have defined in T. When you say `class B extends T`, you're bringing in everything from T *and* A. – Thomas Lockney Mar 22 '11 at 19:36
  • @ThomasLockney You should take a look at http://stackoverflow.com/questions/12854941/why-can-a-scala-trait-extend-a-class I think this is what reguy was referring to – hencrice Aug 02 '15 at 22:31
0

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.

Julien Richard-Foy
  • 9,634
  • 2
  • 36
  • 42