Back to Keywords: static
Q3Question 3 of 4

How does static behave in inheritance?

Key Concepts
  • Static methods are NOT overridden – they are hidden. The method called depends on the reference type, not the object type
  • Static fields are also hidden, not overridden – a subclass can declare the same-named static field, creating two separate fields
  • @Override does not work on static methods – the compiler rejects it
  • Static methods are resolved at compile time (early binding), instance methods at runtime (late binding/polymorphism)
  • Understanding this concept is essential for Java interviews at senior level

Definition

Static methods and fields are hidden, not overridden. The call is resolved by the reference type at compile time, not by the object type at runtime. There is no polymorphism for statics.

Static inheritance rules:

  • Static methods are hidden. A subclass can define a static method with the same signature as the parent's. But the call is resolved by the reference type, not the object type. This is hiding, not overriding.
  • No polymorphism. Parent p = new Child(); p.staticMethod() calls Parent's version because the reference type is Parent.
  • @Override is rejected. The compiler does not allow @Override on a static method because it cannot be overridden.

Each bank branch (subclass) can post its own rate card (static method) on its wall. But when the head office (parent reference) looks up a rate, it reads its own wall, not the branch's. The branch's card is independent, not a replacement.

Understanding the Concepts

What is method hiding vs overriding?

When a subclass defines a static method with the same signature as the parent's static method, the subclass version hides the parent's. The call is resolved by the reference type at compile time, not the object type at runtime. This is fundamentally different from instance methods, which are overridden and resolved by the actual object type at runtime.

JAVA
package com.bank.core;

public class Bank {
    public static String getType() { return "GENERIC"; }   // static
    public String getName() { return "National Bank"; }     // instance
}

public class SavingsBank extends Bank {
    public static String getType() { return "SAVINGS"; }    // HIDES parent static
    @Override
    public String getName() { return "Savings Division"; }  // OVERRIDES parent instance
}
JAVA
Bank b = new SavingsBank();
System.out.println(b.getType());   // "GENERIC" – static: resolved by reference type (Bank)
System.out.println(b.getName());   // "Savings Division" – instance: resolved by object type (SavingsBank)

This is one of the most frequently tested concepts in Java interviews.

Comparison table

| Feature | Instance method | Static method |
|---|---|---|
| Resolved by | Object type (runtime) | Reference type (compile time) |
| @Override | Yes | No (compiler rejects) |
| Polymorphic? | Yes | No |
| Called via | object.method() | ClassName.method() |
| Binding | Late (dynamic dispatch) | Early (compile-time dispatch) |

Can a subclass define the same static field?

Yes, but it creates a separate field (hiding), not an override. Each class has its own independent copy of the field.

JAVA
public class Bank {
    static String country = "INDIA";
}

public class InternationalBank extends Bank {
    static String country = "GLOBAL";  // hides, does not replace
}

System.out.println(Bank.country);              // INDIA
System.out.println(InternationalBank.country); // GLOBAL

Bank b = new InternationalBank();
System.out.println(b.country);  // INDIA (reference type is Bank)

Avoid this pattern. It is confusing and error-prone. Always access static fields via the class name, not an instance reference.

Can you put @Override on a static method?

No. The compiler explicitly rejects @Override on static methods because they cannot be overridden.

JAVA
public class SavingsBank extends Bank {
    // @Override  // COMPILE ERROR: method does not override a superclass method
    public static String getType() { return "SAVINGS"; }
}

How does this work with interface static methods?

Since Java 8, interfaces can have static methods. These are not inherited by implementing classes at all – they can only be called on the interface itself.

JAVA
package com.bank.core;

import java.math.BigDecimal;

public interface InterestCalculator {
    BigDecimal calculate(BigDecimal balance);

    static BigDecimal defaultRate() {
        return new BigDecimal("0.04");
    }
}

public class SavingsInterest implements InterestCalculator {
    @Override
    public BigDecimal calculate(BigDecimal balance) {
        return balance.multiply(InterestCalculator.defaultRate());
    }

    // SavingsInterest.defaultRate() does NOT compile
    // Must use InterestCalculator.defaultRate()
}

This is different from static methods on classes, which are inherited (and can be hidden). Interface static methods are not inherited at all.

What are common mistakes?

  • Assuming static methods are polymorphic. parent.staticMethod() calls the parent's version, not the child's. This is the most common interview mistake.
  • Hiding static fields in subclasses. Creates two independent fields with the same name – deeply confusing.
  • Using @Override on static. It does not compile.
  • Calling static methods on instance references. account.getType() compiles but resolves to the reference type's version, misleading the reader.

What should a senior engineer know?

  • Design implication: If you need polymorphic behavior, use instance methods. Static is the wrong tool for anything that needs to vary by subclass.
  • Factory method pattern: Account.create(type) is static and chooses the subclass internally. This is a design choice that uses static for the entry point but returns polymorphic instances.
  • In Spring, @Bean methods are instance methods on @Configuration classes, not static. Static @Bean methods exist but bypass the CGLIB proxy and lose inter-bean reference resolution.
  • In banking at National Bank of India, Rajesh uses static factory methods like Account.savings(id, balance) to create specific account types, but the methods they call internally are instance methods that support polymorphism.

Visual Overview

DIAGRAM
  Instance method: overriding (runtime dispatch)
    Bank b = new SavingsBank();
    b.getName()  → "Savings Division" (object type wins)

  Static method: hiding (compile-time dispatch)
    Bank b = new SavingsBank();
    b.getType()  → "GENERIC" (reference type wins)

  Rule:
    instance → polymorphic (object type)
    static   → NOT polymorphic (reference type)

Key Takeaway

Static methods and fields are hidden, not overridden. When a subclass defines a static method with the same signature as the parent, the call is resolved by the reference type at compile time, not by the object type at runtime. This means Bank b = new SavingsBank(); b.getType() calls Bank's version, not SavingsBank's.

This is fundamentally different from instance methods, which are resolved by the actual object type at runtime (polymorphism). If you need behavior that varies by subclass, use instance methods, not static.

One sentence to remember: static methods are hidden, not overridden – they are resolved by the reference type at compile time with no polymorphism.

---

Share
Use ← → arrow keys to navigate