8

Coming from Java I am confused by the class/object distinction of scala. Note that I do not ask for the formal difference; there are enough references on the web which explain this, and there are related questions on SO.

My questions are:

  1. Why did the designers of scala choosed to make things more complicated (compared to Java or C#)? What disadvantages do I have to expect if I ignore this distinction and declare only classes?

Thanks.

Community
  • 1
  • 1
John
  • 97
  • 1
  • 2
    Why do you consider the approach Scala took to be more "complicated"? After working with each languages Scala's solution is by far the easiest, especially when inheritance and sub-typing come into play. – soc Aug 07 '11 at 14:09

3 Answers3

24

Java classes contain two completely different types of members -- instance members (such as BigDecimal.plus) and static members (such as BigDecimal.valueOf). In Scala, there are only instance members. This is actually a simplification! But it leaves a problem: where do we put methods like valueOf? That's where objects are useful.

class BigDecimal(value: String) {
   def plus(that: BigDecimal): BigDecimal = // ...
}

object BigDecimal {
   def valueOf(i: Int): BigDecimal = // ...
}

You can view this as the declaration of anonymous class and a single instantiation thereof:

class BigDecimal$object {
   def valueOf(i: Int): BigDecimal = // ...
}
lazy val BigDecimal = new BigDecimal$object

When reading Scala code, it is crucial to distinguish types from values. I've configured IntelliJ to hightlight types blue.

val ls = List.empty[Int]  // List is a value, a reference the the object List
ls: List[Int]             // List is a type, a reference to class List

Java also has another degree of complexity that was removed in Scala -- the distinction between fields and methods. Fields aren't allowed on interfaces, except if they are static and final; methods can be overriden, fields instead are hidden if redefined in a subclass. Scala does away with this complexity, and only exposes methods to the programmer.

Finally, a glib answer to your second question: If you don't declare any objects, you're program may never run, as you to define the equivalent of public static void main(String... args) {} in Scala, you need at least one object!

retronym
  • 54,768
  • 12
  • 155
  • 168
  • The object keyword gives you a singleton class (under-the-hood anyway) and is Scala's replacement for static members. – jyoungdev Jun 27 '10 at 20:42
  • 3
    Be aware that if you have a class named `Something` and an object named `Something` (in the same package), then those two are linked - the object is the *companion object* of the class, and the two can see each other's private members. Comparing it with Java: think of the methods in the class as the instance methods, and the methods in the object as the static methods that belong to that class. – Jesper Jun 27 '10 at 20:55
  • 1
    Good point, Jesper. In addition, the companion object `T` of a class or trait `T` is in the implicit scope when searching for implicit values a type `X`, given that `T` or a subtype of `T` is a part of type `X`. This is used to find implicit views and implicit arguments. – retronym Jun 27 '10 at 21:37
2

Scala doesn't have any notion of static methods with standard classes, so in those scenarios you'll have to use objects. Interesting article here which provides a good intro:

http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-3

(scroll down to Scala’s Sort-of Statics)

Roy Truelove
  • 22,016
  • 18
  • 111
  • 153
0

One way to look at it is this. An executing program consists of a community of objects and threads. Threads execute code within the context of objects -- i.e. there is always a "this" object that a thread is executing within. This is a simplification from Java in the sense that in Java, there is not always a "this". But now there is a chicken/egg problem. If objects are created by threads and threads are executed within objects, what object is the first thread initially executing within. There has to be a nonempty set of objects that exist at the start of program execution. These are the objects declared with the object keyword.

Theodore Norvell
  • 15,366
  • 6
  • 31
  • 45