2

Many oo languages have some facility for class methods and class variables. Ruby for example allows this with metaclasses. Is it fair to look at companion objects in a similar fashion in Scala?

jmazin
  • 1,021
  • 9
  • 11
  • Can you elaborate on what you consider to be a "class method" and "class variable?" I hear those and think, "there's always methods and variables associated with a class." – wheaties Jan 14 '14 at 21:12
  • @wheaties This [answer](http://stackoverflow.com/questions/3802540/difference-between-class-variables-and-class-instance-variables) may help. Objects are all (ideally) instances of _some_ class. And classes are objects! So they are _also_ instances of some object. Let's say we want to know how many instances of a class exist. We can store that number in the class itself. So it's a class variable. The terminology is also confusing, a 'class instance variable' is what is normally just called an 'instance variable'. – jmazin Jan 15 '14 at 00:03

2 Answers2

2

Is it fair to looks at companion objects in a similar fashion in Scala?

Yes, that's a reasonable way to think about them.

Larsenal
  • 49,878
  • 43
  • 152
  • 220
2

On JVM classes are not objects in the same sense as in Ruby or other dynamic languages. Sure, you can get representation of a class as a special object of class Class[_], but it is used primarily for reflection and cannot have custom methods, for example. However, JVM has notion of static methods and fields, which are associated with a class and does not require objects of the class to be used:

public class SomeClass 
    public static int add(int x, int y) { return x + y; }
}

public class OtherClass {
    public static void main() {
        int z = SomeClass.add(1, 2);
    }
}

These methods and fields are essentially "global" (unless we're considering class loaders mechanism), and methods, for example, cannot be overridden in subclasses.

Scala does not let you define and use statics directly - there is no notion of "static" in the language. However, in Scala you can define singleton objects which can be used to emulate static fields and methods and at the same time are much more powerful than statics, for example, they can participate in inheritance. Internally these objects are instances of special class generated by Scala compiler for you.

Also Scala has special kind of these singleton objects, called companion objects, which share the name with some class:

class SomeClass

object SomeClass

Internally these objects are instances of completely different class than SomeClass (it can be accessed as SomeClass.type), but Scala treats them in special way, for example, you can access SomeClass private members from SomeClass companion object and vice versa. Also companion objects provide additional implicit scope. However, SomeClass.type and SomeClass are completely different classes.

In short, yes, you can think of companion objects as containers for "class" methods and fields, but only to some extent. Companion objects are not metaclasses in any way; they have completely different semantics and implementation.

Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296