Are Static Methods Inherited in Java

Are static methods inherited in Java?

All methods that are accessible are inherited by subclasses.

From the Sun Java Tutorials:

A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent. You can use the inherited members as is, replace them, hide them, or supplement them with new members

The only difference with inherited static (class) methods and inherited non-static (instance) methods is that when you write a new static method with the same signature, the old static method is just hidden, not overridden.

From the page on the difference between overriding and hiding.

The distinction between hiding and overriding has important implications. The version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked depends on whether it is invoked from the superclass or the subclass

Why are class static methods inherited but not interface static methods?

Here's my guess.

Since Cat can only extend one class if Cat extends Animal then Cat.identify has only one meaning. Cat can implement multiple interfaces each of which can have a static implementation. Therefore, the compiler would not know which one to choose?

However, as pointed out by the author,

Java already has this problem, with default methods. If two interfaces
declare default void identify(), which one is used? It's a compile
error, and you have to implement an overriding method (which could
just be Animal.super.identify()). So Java already resolves this
problem for default methods – why not for static methods?

If I was to guess again, I'd say that with default the implementation is part of Cat's vtable. With static it cannot be. The main function must bind to something. At compile time Cat.identify could be replaced with Animal.identify by the compiler but the code wouldn't match reality if Cat was recompiled but not the class that contains main.

Static methods between inheritance classes - Java

We can declare static methods with same signature in subclass, but it is not considered overriding as there won’t be any run-time polymorphism.

If a derived class defines a static method with same signature as a static method in base class, the method in the derived class hides the method in the base class.

/* Java program to show that if static method is redefined by 
a derived class, then it is not overriding. */

// Superclass
class Base {

// Static method in base class which will be hidden in subclass
public static void display() {
System.out.println("Static or class method from Base");
}

// Non-static method which will be overridden in derived class
public void print() {
System.out.println("Non-static or Instance method from Base");
}
}

// Subclass
class Derived extends Base {

// This method hides display() in Base
public static void display() {
System.out.println("Static or class method from Derived");
}

// This method overrides print() in Base
public void print() {
System.out.println("Non-static or Instance method from Derived");
}
}

// Driver class
public class Test {
public static void main(String args[ ]) {
Base obj1 = new Derived();

// As per overriding rules this should call to class Derive's static
// overridden method. Since static method can not be overridden, it
// calls Base's display()
obj1.display();

// Here overriding works and Derive's print() is called
obj1.print();
}
}

Output:

Static or class method from Base

Non-static or Instance method from
Derived

Following are some important points for method overriding and static methods in Java.

1) For class (or static) methods, the method according to the type of reference is called, not according to the object being referred, which means method call is decided at compile time.

2) For instance (or non-static) methods, the method is called according to the type of object being referred, not according to the type of reference, which means method calls is decided at run time.

3) An instance method cannot override a static method, and a static method cannot hide an instance method. For example, the following program has two compiler errors.

4) In a subclass (or Derived Class), we can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass methods — they are new methods, unique to the subclass.

Source

Java 8: Better to extend class of static methods or better to call static methods directly?

Static members aren't "inherited" per se. They live on the base class regardless of which subclass they're called from, so I doubt there's any memory impact.

The reason for creating all classes as a subclass of this common class is just for easy access to static members without the qualifying class name. A common variation is to inherit from an interface that declares a bunch of static fields. The upside is that implementing an interface doesn't interfere with inheritance the way a superclass would (you can only extend a single superclass). The downside is that until Java 8 it wasn't possible to declare static methods on an interface.

In any case, this trick is generally considered an anti-pattern and has been superseded by static imports.

Inheritance vs Static in Java

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.

How to properly proxy inherited static methods?


As you say, static methods are not inherited. That means that only instance methods are inherited.
The only ways you can call two different functions with one call operation is if:

  • it's invoking an instance method (incl. getters, setters and operators), or
  • it's invoking a function value.

That is:

callA(o) => o.foo(42);  // Instance method.
callB(f) => f(42); // Function value.

In all other situations, the function to call is determined statically, so you will always call exactly the same function. You can't make your greet function call different functions depending on how it's called unless it's an instance method itself or it takes a parameter that helps it choose.

In other words, don't try to do clever stuff with static functions.
You are trying to have the CasualEnglish versions of sayGreeting and actGreeting override the ones in English. That can only work if they are instance members.

Why does my static block allows to call parent class static method without using parentclass reference?

Static method n() is inherited by subclass myclass, so you can call it directly in the static block of myclass.

Static methods not inherited?

It's fair to assume this is a design choice, and a wise one.

Inheritance is a mechanism for objects to override certain behaviors.

Animal a = new Dog();
Animal b = new Cat();
// a and b, although both animals, they will behave differently

What would be the point of static inheritance? The functions are static, they belong directly to the class. Hence there is no instanciation, no polymorphism, and "inheriting" static functions makes little sense in that context.

Are static variables inherited

Please have a look into the documentation of oracle: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#d5e12110

Static variables are inherited as long as they're are not hidden by another static variable with the same identifier.



Related Topics



Leave a reply



Submit