Emmy
Emmy

Reputation: 145

Why and When there is need to re-declare static method in derived class if its definition cannot overridden/altered by derived class?

I am familiar with static keyword, and how it used. I understand that a static method can be re-declared in sub-class but its definition gets hidden and remains same as of parent class. I am mentioning some links of articles I've already read:

https://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/

Why doesn't Java allow overriding of static methods?

Difference between Static and final?

When 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. But still the method of base class is called such as display() method of base class.

But I am curious as to why and when there is a need to re-declare static method of base class in derived class if its definition cannot overridden/altered in the derived class and the definition of base class is displayed instead?

    /* 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();    
    } 
} 

Upvotes: 0

Views: 398

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

The main take-away here is: Don't use instance variables to call static functions. Java allows it, but it's confusing because it looks like an instance method call when it isn't.

This line creates a Derived instance, and assigns it to a Base-typed variable:

Base obj1 = new Derived(); 

Later, when you type:

obj1.display();

what really happens is:

Base.display();

because obj is a variable of type Base and display is a static method. In fact, if you look at the compiled bytecode, you see that it's literally that call, the instance variable isn't mentioned anywhere:

public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class Derived
       3: dup
       4: invokespecial #3                  // Method Derived."":()V
       7: astore_1
       8: aload_1
       9: pop
      10: invokestatic  #4                  // Method Base.display:()V
      13: aload_1
      14: invokevirtual #5                  // Method Base.print:()V
      17: return
}

Notice the difference between the obj1.display() call

      10: invokestatic  #4                  // Method Base.display:()V

and the obj1.print() call:

      13: aload_1
      14: invokevirtual #5                  // Method Base.print:()V

The static call doesn't push obj1 on the stack, and uses invokestatic. The instance call does push obj1 on the stack (aload_1), and calls invokevirtual.

If you declared obj1 of type Derived, you'd see the opposite behavior. With:

Derived obj1 = new Derived(); 

then

obj1.display();

outputs:

Static or class method from Derived

because it's really:

Derived.display();

It's all about the type of the instance variable. The type of the instance itself doesn't matter at all (in fact, obj1 could be null).

Don't call static methods via instance variables. Instead, use the class name.

I understand that a static method can be re-declared in sub-class but its definition gets hidden and remains same as of parent class.

...

When 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.

Those two statements contradict each other. The relationship is this: The derived static method overrides the base static method when referenced via the derived class. So with your code, Base.display references Base.display and Derived.display references Derived.display. The fact there's a display on Derived doesn't affect the one on Base, which is still accessible via Base (or a Base-typed variable). (If you didn't have display in Derived, Derived.display would reference Base.display, but since you do, it doesn't.)

But I am curious as to why and when there is a need to re-declare static method of base class in derived class...

The only time you need that is if you want Derived.display (or obj1.display when obj1 is declared as Derived) to do something different from Base.display (or obj1.display when obj1 is declared as Base). One example I can think of is methods that create instances, perhaps via the Builder pattern:

Base b = Base.builder()
         .setName("the name")
         .setAnswer(42)
         .setBiz("baz")
         .build();

vs.

Derived d = Derived.builder()
         .setName("the name")
         .setAnswer(42)
         .setBiz("baz")
         .setDerivedThingy("whatever")
         .build();

Upvotes: 6

Jaspreet Jolly
Jaspreet Jolly

Reputation: 1313

There is no need for an instance while invoking static member or method.

Since static members belongs to class rather than instance.

Example 15.11.1-2. Receiver Variable Is Irrelevant For static Field Access

The following program will make your doubt clear.It demonstrates that a null reference can also be used to access a class (static) variable without causing any Null pointer exception:

class Test {
    static String name = "Jaspreet";
    static Test method1(){
        System.out.print("Hello world");
        return null;
    }
    public static void main(String[] args) {
        System.out.println(method1().name);
    }
}

And the analysis of why it is happening

Even though the result of method1() is null, a NullPointerException is not thrown. That "Hello world" is printed demonstrates that the Primary expression is indeed fully evaluated at run time, despite the fact that only its type, not its value, is used to determine which field to access (because the field name is static).

Upvotes: 1

Related Questions