Take the 2-minute tour ×

It's not much of a question, it's rather my excitement that it's possible at all! I wrote this little example just to prove the opposite - I expected either a compiler error or one of the values (111 or 222, I wasn't sure).

scala> trait T1 { private val v = 111; def getValueT1 = v }
scala> trait T2 { private val v = 222; def getValueT2 = v }
scala> class T12 extends T1 with T2                        
scala> val t = new T12                                     
scala> t.getValueT1                                        
res9: Int = 111
scala> t.getValueT2                                        
res10: Int = 222

Why doesn't the v get overridden? Off course this works only as long as vs are private, but still.

share|improve this question

3 Answers 3

up vote 12 down vote accepted

Since traits are not just interfaces, they need some way to store their internal state. But they have to be compatible with interfaces--so what do they do? They create accessors for what looks like a field (as you can see (among other things) with javap -l -s -c -private on the class files):

public interface T1 extends java.lang.Object {
public abstract int T1$$v();
Signature: ()I

public abstract int getValueT1();
Signature: ()I

and then create an implementation class that has static methods to implement the functionality:

public abstract class T1$class extends java.lang.Object {
public static int getValueT1(T1);
  Signature: (LT1;)I
   0:   aload_0
   1:   invokeinterface #12,  1; //InterfaceMethod T1.T1$$v:()I
   6:   ireturn

Now, hopefully, it's clear that these would be separate by default since these internally-generated methods have the name of the trait in the name of the method. And when we look in the implementation in T12:

public class T12 extends java.lang.Object implements T1,T2,scala.ScalaObject {
private final int Overridden$T1$$v;
  Signature: I

public final int T1$$v();
  Signature: ()I
   0:   aload_0
   1:   getfield    #22; //Field T1$$v:I
   4:   ireturn

public int getValueT1();
  Signature: ()I
   0:   aload_0
   1:   invokestatic    #29; //Method T1$class.getValueT1:(LT1;)I
   4:   ireturn

you can see that it just fills in what's needed for each specific trait. Now the question is--how do traits ever overwrite each other? They seem to be completely separate! That's the compiler's job. If something is private it's hidden and can't be overridden, so it doesn't matter that another (private) thing has the same name. But if it's not, the compiler complains of a collision:

error: overriding value v in trait T1 of type Int;
 value v in trait T2 of type Int needs `override' modifier
  class T12 extends T1 with T2

because now it's not using the secret mangled names with the trait name embedded. (Observe that getValueT1 is not mangled in this example.)

share|improve this answer
Nice answer. A slight correction - T1$class is called the implementation class. –  axel22 Mar 5 '11 at 14:29
Indeed--a companion class is something else. Fixed. –  Rex Kerr Mar 5 '11 at 14:51
Excellent answer, thank you. –  Vilius Normantas Mar 6 '11 at 16:36

This is not a property particular to traits. For instance:

scala> class X {
     |   private val v = 111
     |   def getX = v
     | }
defined class X

scala> class Y extends X {
     |   private val v = 222
     |   def getY = v
     | }
defined class Y

scala> new Y
res0: Y = Y@5ca801b0

scala> res0.getX
res1: Int = 111

scala> res0.getY
res2: Int = 222

And the same holds true in Java. Private members are private. They belong solely to where they were defined, and have no effect outside. If there was a conflict through inheritance, they would be visible, which would defeat the purpose of being private.

share|improve this answer
Now I'm a bit embarrassed to be so excited about such a trivial thing :) I guess I just was too focused on traits to see the broader picture. –  Vilius Normantas Mar 6 '11 at 16:35
@Vilius Well, it looks trivial from the Scala side. When one comes from Java, which is so full of limitations, it does look special. –  Daniel C. Sobral Mar 6 '11 at 17:05

Private members and methods can't be overridden. It is to prevent changes in class behaviour injected by descendants. The concept here is very simlar to C++ one - each ancestor holds its own copy of members until a special methods (virtual inheritance, for example) is invoked.

share|improve this answer

Your Answer


