object ScalaTrueRing {
def rule = println("To rule them all")
}
this piece of code will be compiled into java byte code, if I decompile it, then the equivalent Java code is similar to this:
public final class JavaTrueRing
{
public static final void rule()
{
ScalaTrueRing..MODULE$.rule();
}
}
/* */ public final class JavaTrueRing$
/* */ implements ScalaObject
/* */ {
/* */ public static final MODULE$;
/* */
/* */ static
/* */ {
/* */ new ();
/* */ }
/* */
/* */ public void rule()
/* */ {
/* 11 */ Predef..MODULE$.println("To rule them all");
/* */ }
/* */
/* */ private JavaTrueRing$()
/* */ {
/* 10 */ MODULE$ = this;
/* */ }
/* */ }
it's compiled into two classes, and if I use Scala.net compiler, it'll be compiled into MSIL code, and the equivalent C# code is like this:
public sealed class ScalaTrueRing
{
public static void rule()
{
ScalaTrueRing$.MODULE$.rule();
}
}
[Symtab]
public sealed class ScalaTrueRing$ : ScalaObject
{
public static ScalaTrueRing$ MODULE$;
public override void rule()
{
Predef$.MODULE$.println("To rule them all");
}
private ScalaTrueRing$()
{
ScalaTrueRing$.MODULE$ = this;
}
static ScalaTrueRing$()
{
new ScalaTrueRing$();
}
}
It's also compiled into two classes.
Why do Scala compilers(the one for Java and the one for .NET) do this? Why does not it just call the println method in the static rule method?
A companion object is an object that's declared in the same file as a class , and has the same name as the class. A companion object and its class can access each other's private members. A companion object's apply method lets you create new instances of a class without using the new keyword.
In scala, when you have a class with same name as singleton object, it is called companion class and the singleton object is called companion object. The companion class and its companion object both must be defined in the same source file.
Difference Between Scala Classes and Objects Definition: A class is defined with the class keyword while an object is defined using the object keyword. Also, whereas a class can take parameters, an object can't take any parameter. Instantiation: To instantiate a regular class, we use the new keyword.
In Scala, an object is a named instance with members such as fields and methods. An object and a class that have the same name and which are defined in the same source file are known as companions. Companions has special access control properties, which is covered under Scala/Access modifiers.
It is important to understand that in scala, an object
actually is a first class citizen: it is an actual instance that can be passed around as any other object.
By 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 with static methods, our singleton object has full polymorphic beheviour. doSomething
will indeed call our overriden hello
and bye
methods, and not the default implementations:
bonjour
... doing some work ...
au revoir
So the object
implementation must necessarily be a proper class. But for interoperability with java,
the compiler also generates static methods that just forward to the unique instance (MODULE$
) of the class (see JavaTrueRing.rule()).
This way, a java program can access the methods of the singleton object as a normal static method.
Now you might ask why scala does not put the static method forwarders in the same class as the instance methods. This would 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;
}
// Forwarders
public static final void rule() {
MODULE$.rule();
}
}
I believe that the main reason why this can't be as simple is because in the JVM you cannot have in the same class an instance method and a static method wth the same signature. There might be other reasons though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With