It is important to understand that in scala, an object actually a first-class citizen: it is an actual instance that can be transferred like any other object. Example:
trait Greetings { def hello() { println("hello") } def bye() { println("bye") } } object FrenchGreetings extends Greetings { override def hello() { println("bonjour") } override def bye() { println("au revoir") } } def doSomething( greetings: Greetings ) { greetings.hello() println("... doing some work ...") greetings.bye() } doSomething( FrenchGreetings )
Unlike static methods, our singleton object has a full polymorphic beheviour. doSomething will actually call our overridden hello and bye methods, not standard implementations:
bonjour ... doing some work ... au revoir
Thus, the implementation of object must necessarily be the proper class. But to interact with java, the compiler also generates static methods that are simply passed to the unique instance ( MODULE$ ) of the class (see JavaTrueRing.rule ()). Thus, a java program can access the methods of a single object as a regular static method. You may now ask why scala does not put static forwarding methods in the same class as instance methods. This will give us something like:
public final class JavaTrueRing implements ScalaObject { public static final MODULE$; static { new JavaTrueRing(); } public void rule() { Predef.MODULE$.println("To rule them all"); } private JavaTrueRing() { MODULE$ = this; }
I believe that the main reason why this cannot be so simple is that in the JVM you cannot have an instance method and a static wth method of the same signature in the same class. However, there may be other reasons.
source share