tags:

views:

282

answers:

6

I dont quite understand why Static methods can be inherited in Java ?

Inheritance is like inheriting from the base class AND Static belongs to the Class and not Object.

So if the Static belongs to the Class only why does it trickle down to the derived class ? Shouldn't it just stay with the Class in which it was defined ?

Is Inheriting Static methods a good programming practise ?

+2  A: 

As you state, the static method belongs to the class and since inheritance describes a IS-A relationship between types does it not stand to reason that a subclass would inherit all of the members of its superclass?

I personally think this implementation makes a lot of sense!

Andrew Hare
Technically static methods do not belong to anyone or anything, if you're using reflection you can invoke them against any object no matter what their class is and they'll work.
Esko
I see your point but unfortunately you are conflating two different concepts. Static methods do not belong to any *instance* of a type but they do belong to the type itself. When you use reflection you must provide the type to find that static method but you are not required to provide an instance upon which to invoke the method.
Andrew Hare
+7  A: 

In java static methods are not inherited (or the right word is overridden) but they can be hidden.

The big different here is that they are not subjected to polymorphism as object method are.

public class C1 {

    static public void M1() {
        System.out.println("C1.M1().");
    }

    static public void main(String ... Args) {
        M1();
    }

}

public class C2 extends C1 {

    static public void M1() {
        System.out.println("C2.M1().");
    }

    static public void main(String ... Args) {
        M1();
        C1.main(Args);
    }

}

When run C2.main(null), you will get:

C2.M1().
C1.M1().

As you can see,

calling M1() in C1.main(...) refer to M1 of C1 and

calling M1() in C2.main(...) refer to M1 of C2.

The invocation of M1 (with out any prefix, see the first line of each main()), are not subjected to polymorphism as M1 in C1 does not get overrided by C2.

But calling from C2 refer to M1 of C2 as M1 of C2 is hide the one in C1.

Read more here.

EDIT: I've just re-read your question and just see the part about "good programming practise".

As I said, static method are not inherited but hidden so they are as good as different method.

From a code's point of view, they are completely different methods.

Let say.

C1                has static method M1.
C2 extends C1 and has static method M1.
C3 extends C2.

When call M1 (without prefix) from C1, you call C1.M1(). When call M1 (without prefix) from C2, you call C2.M1(). // derive but get hidden When call M1 (without prefix) from C3, you call C3.M1(). // derive and no hidden

To specify which method, use class name like C1.M1(), C2.M1() and C3.M1() (this will called C2.M1()).

So this implementation allows static method to be reimplemented but only as a different method not as an overridden (or replacement) method.

Therefore, this usually no different from let say naming them differently like: C1_M() and C2_M().

So you may ask, why bother having this feature? I don't really know. Perhaps allows a more flexible naming to method.

But there is usage (that might or might not be intented) that I used is polymorphism via reflection.

Since you can get and call a method by name using reflection, allowsing them to have a same name will enable polymorphism when do via reflection.

For example (rought code, may not run):

String aClsName = "C1"; // "C2";
Class aCls = Class.forName(aClsName);
Method   aMth = aCls.getMethod("M1");   // M1 of C1 or C2 depends on the class name.
aMth.invoke(null);

OR

Object aObj = new C1(); // new C2();
Class aCls = aObj.getClass();
Method   aMth = aCls.getMethod("M1");   // M1 of C1 or C2 depends on the class of the object.
aMth.invoke(null);

When think about it, I think Java has use this too (like, writeObject(...) for serialization) so it may be intented.

So to conclude, hiding static method is not a good programming practice (Eclipse also recommend against it) but it can be useful in two cases, (1) to name the method exact what it suppose to do and (2) to polymorph it using reflection.

Hope this helps.

NawaMan
I think Static methods are Inherited. I am attaching the code below as an answer. Can you explain that ?
Geek
There are number of terminology that can be confused here. inherit, derive, override, hide, overload. In this case, static methods are inherit in the sense that you can use it in subclass (so I can call C3.M1() and it will invoke C2.M1() when C3 does not have M1) but in may OOP book, the word inherit also imply polymorphism which my answer explains that it is not the case for static method. Static method does not allows overriding thus they are not subjected to polymorphism. Therefore, I said that static methods are not inherit in that sense (they can be derived). It is a matter of terminology
NawaMan
A: 
public class StaticTest extends StaticBase {

public static void main(String[] args) {
 // TODO Auto-generated method stub
 System.out.println("Start");
 StaticTest.printIt();
}

}

class StaticBase{

public static void printIt(){
 System.out.println("Inside bas Class");
}

}

Does this code not prove that Static is Inherited ??

Geek
As I said before, it is about terminology. If look up the meaning of "inherit" from the dictionary, YES, static method can be inherited. However, in OOP, the word also implies polymorphism which static methods does not subject to (different from object methods).
NawaMan
@Geek - no it does not prove it. Because that is not inheritance in the OOP sense. If you don't believe me, read the Java Language Specification.
Stephen C
+3  A: 

I dont quite understand why Static methods can be inherited in Java ?

The short answer is that statics are NOT inherited in Java. Rather, the static members declared in a class are (subject to "access" restrictions) directly visible in the namespace of derived classes, unless they "hidden" by declarations in the derived class.

So if the Static belongs to the Class only why does it trickle down to the derived class ? Shouldn't it just stay with the Class in which it was defined ?

Trickle down is not a technical term. But that's not what is happening anyway. The static members of the class are not members of the derived class.

Is Inheriting Static methods a good programming practise ?

You cannot stop it happening!

Just FYI, here are some "good practice" issues related to statics:

  • Mutable static attributes should be private, and preferably recast as Singleton objects.

  • A lot of statics members (methods or attributes) or even Singletons, can be a sign of a bad design. It is certainly not "the object-oriented way".

  • In some kinds of application (e.g. web apps), even Singleton objects are problematic.

  • It is bad practice to refer to a static method a obj.someStaticMethod() or this.someStaticMethod(). Either qualify the static name with the class name, or refer to it without qualification.

  • It is (arguably) better to qualify a reference to a static in superclass; e.g. in SubClass, refer to SuperClass.someStaticMethod() rather than someStaticMethod(). (But the downside is that the code is more verbose. This falls under the same banner as the pros and cons of importing.)

  • static final constants should be declared with all-caps names.

Stephen C
A: 

If B is a subclass of A and we have A a = new B(); as a legal statement hence they are the same type and if the static method is on A then B will have it since they are of the same type in that regard. I think your confusion lies with the fact that static methods can be referenced via this making it seem as if they are inherited.

It is bad practice to dispatch a static method via an instance of the class so it should always be A.staticMethod() which also clears up the inheritance misconception you have as B.staticMethod() would not refer to the same method as A if hidden/overriden.

non sequitor
A: 

For method invocation using inheritance to take place, you need to have one instance of the class.

Since static method do not have an instance, the method definition is attached to the class it self ( no dynamic dispatch )

That's more or less the rationale in my own words.

It is more a technical problem ( with the implementation ) than a language feature.

As for:

Is Inheriting Static methods a good programming practise ?

No, it is not. This is hard specially when you come from an structured programming language, eventually it would make sense.

I don't really use much static methods in first place.

OscarRyz