Why do static members make a language less object oriented?

I am studying Scala at the moment, and I came across this statement in the Odersky Programming Scala 2nd edition:

One way Scala is more object oriented than Java is that classes in Scala cannot have static members.

I'm not good at Java or Scala to understand this comparison. Why do static members make the language smaller than OO?

+6
source share
6 answers

Odersky’s statement is valid and significant, but some people don’t understand what he meant.

Let's say that in Java you have a Foo class with the f method:

class Foo { int f() { /* does something great */ } } 

You can write a method that takes Foo and calls f on it:

 void g(Foo foo) { foo.f(); } 

Perhaps there is a SubFoo class that extends Foo; g is also working on this. There may be a whole set of classes, inherited or interface, that share the fact that they can be used with g.

Now make this method f static:

 class Foo { static int f() { /* does something great */ } } 

Is it possible to use this new Foo with g, maybe so?

 g(Foo); // No, this is nonsense. 

darn. Well, let it change the signature of g so that we can pass Foo to it and call it f.

O'ops - we cannot. We cannot pass a reference to Foo because Foo is not an instance of any class . Some people commenting here are confused by the fact that there is a class object corresponding to Foo, but as Sotirios tried to explain, this class object does not have a method f, and Foo is not an instance of this class. Foo is not an example of anything; it is not an object at all. The class object for Foo is an instance of the Class class that contains information about Foo (think of it as the internal Wikipedia page of Foo) and is completely irrelevant to the discussion. Wikipedia page for “tiger” is not a tiger.

In Java, “primitives,” such as 3 and “x,” are not objects. These are objects in Scala. For performance, your program will use JVM primitives for 3 and "x" whenever possible at runtime, but at the level you code, they really are objects. The fact that they are not objects in Java has rather adverse consequences for anyone trying to write code that processes all types of data — you must have special logic and additional methods to cover primitives. If you have ever seen or written such code, you know that it is terrible. The Oder affirmation is not "purism"; far from him.

In Scala, there is no part of the run-time data that is not an object, and there is no way to call methods that are not an object. In Java, none of these statements are true; Java is a partially object oriented language. In Java, there are things that are not objects, and there are methods that are not related to objects.

Scala newbies often think of object Foo as some kind of weird replacement for Java statics, but that you need to get through quickly. Instead, think of Java static methods as non-OO warts and Scala object Foo { ... } as something like this:

 class SomeHiddenClass { ... } val Foo = new SomeHiddenClass // the only instance of it 

Here, Foo is a value, not a type, and it really is an object. It can be passed to the method. It can extend some other classes. For instance:

 abstract class AbFoo { def f:Int } object Foo extends AbFoo { def f = 2 } 

Now finally you can say

 g(Foo) 

It is true that the “companion object” for the class is a good place to host methods and data other than the instance for the class. But this companion object is an object, so the usual rules and possibilities apply.

The fact that in Java you put such methods on non-objects, restricting their use is a commitment, not a function. This, of course, is not OO.

+3
source

I'm not sure that I will fully buy this argument, but here is one of the possible arguments.

For an object-oriented purist, everything must be an object, and the whole state must be encapsulated by objects. Any member of a static class is a state by definition that exists outside the object, because you can use it and manipulate it without instantiating the object. Thus, the absence of static class members makes a cleaner object-oriented language.

+5
source

Well, with static members like methods, you have no objects to create, and yet you can call such static methods. You only need a static class name to set the namespace for these methods, for example:

 long timeNow = System.currentTimeMillis(); // no object creation 

It rather gives a feeling, like in procedural languages.

+1
source

static members belong to a class other than an object, while the basic concept of oop lies between the relationship between the individual objects of the dirrefer class.

+1
source

A static method in Java is one that works with the class itself and does not need to create an object first. For example, this line:

 int c = Integer.parseInt("5"); 

Integer.parseInt() is static because I didn’t have to go Integer i = new Integer(); before using it; this does not work on any particular object that I created, since it will always be the same and more like a typical call to a procedural function instead of an object-oriented method. This is more object-oriented if I need to create an object for each call, and we encapsulate everything like this rather than letting static use methods as artificially-procedural functions.

+1
source

There are several competing definitions of what object orientation means. However, there is one thing that everyone can agree on: dynamic dispatch is a fundamental part of defining OO.

Static methods are static (duh), not dynamic; ergo, by definition, they are not object-oriented.

And logically, a language that has an object that is not object oriented is, in a sense, “less OO” than a language that does not have the specified function.

+1
source

All Articles