34

I know that we cannot override static methods in Java, but can someone explain the following code?

class A {
    public static void a() { 
        System.out.println("A.a()");
    }
}   

class B extends A {
    public static void a() {
        System.out.println("B.a()");
    }
}

How was I able to override method a() in class B?

RaminS
  • 2,208
  • 4
  • 22
  • 30
  • 13
    Because you didn't. `B.a()` is only accessible via class `B`. If you have something like `A a = new B(); a.a();`, it will print "A.a()", even though it's of type B. If it were truly overridden, then it would have printed "B.a()". Note that it is Java's odd feature that allows you to call static methods from an object instance that helps sow confusion here. – dlev May 17 '13 at 20:33
  • 1
    What makes you think that you override `a` inside `B`? You can test that easily by adding `@Override` annotation before that method. – Pshemo May 17 '13 at 20:34
  • You can test if `a()` is inherited by `B` if you remove the `a()` function from `B`. It does inherit, but it does not override. Instead it hides `a()` if you declare another `a()` function in `B`. – Dorus May 17 '13 at 20:56
  • @Dorus dlev understand now. thank u. –  May 17 '13 at 21:10

9 Answers9

54

You didn't override anything here. To see for yourself, Try putting @Override annotation before public static void a() in class B and Java will throw an error.

You just defined a function in class B called a(), which is distinct (no relation whatsoever) from the function a() in class A.

But Because B.a() has the same name as a function in the parent class, it hides A.a() [As pointed by Eng. Fouad]. At runtime, the compiler uses the actual class of the declared reference to determine which method to run. For example,

B b = new B();
b.a() //prints B.a()

A a = (A)b;
a.a() //print A.a(). Uses the declared reference's class to find the method.

You cannot override static methods in Java. Remember static methods and fields are associated with the class, not with the objects. (Although, in some languages like Smalltalk, this is possible).

I found some good answers here: Why doesn't Java allow overriding of static methods?

Community
  • 1
  • 1
goblinjuice
  • 3,184
  • 24
  • 26
  • 6
    You claim static methods are not inherited, but if i remove `a()` from `B` then `B.a();` suddenly prints "A.a()". You do inherit static methods, but you do not override them. Instead, you hide them as Eng.Fouad mentioned in his answer. – Dorus May 17 '13 at 20:49
  • 1
    @Dorus don't see inheritance mentioned anywhere! –  May 17 '13 at 21:12
  • Indeed inheritance was not mentioned, but the before the edit this answer made it look like static methods where not inherited, or, was at least incomplete. – Dorus May 17 '13 at 21:30
9

That's called hiding a method, as stated in the Java tutorial Overriding and Hiding Methods:

If a subclass defines a class method with the same signature as a class method in the superclass, the method in the subclass hides the one in the superclass.

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 1
    hmmm... not exactly sure if this is method hiding. Both `A` and `B` have `static a()` and depending on the declared reference type, the compiler will find and call the right function. E.g. `A a = new B(); a.a(); //prints A.a() since the compiler looks at the declared reference of a which is A` – goblinjuice May 17 '13 at 20:45
  • 1
    @goblinjuice Declaring `a()` in `B` would hide `A`'s `a()` from `B`. – Eng.Fouad May 17 '13 at 20:47
  • 2
    @goblinjuice This is the *literal definition of hiding* in Java. – dlev May 17 '13 at 20:50
6

static methods are not inherited so its B's separate copy of method

static are related to class not the state of Object

jmj
  • 237,923
  • 42
  • 401
  • 438
  • 6
    This is wrong, you do inherit static methods, but the mechanism for declaring another method with the same signature in a subclass is called hiding and works slightly different then overriding. – Dorus May 17 '13 at 20:54
  • how do you inherit static methods @Dorus ? – jmj May 17 '13 at 20:55
  • 1
    +1 for @Dorus... static methods are NOT inherited as he showed in the previous comment. –  May 17 '13 at 21:13
3

You didn't override the method a(), because static methods are not inherited. If you had put @Override, you would have seen an error.

A.java:10: error: method does not override or implement a method from a supertype
    @Override
    ^
1 error

But that doesn't stop you from defining static methods with the same signature in both classes.

rgettman
  • 176,041
  • 30
  • 275
  • 357
2

Also, the choice of method to call depends on the declared type of the variable.

B b = null;
b.a(); // (1) prints B.a()
A a = new B();
a.a(); // (2) prints a.a() 

At (1), if the system cared about the identity of b, it would throw a NPE. and at (2), the value of a is ignored. Since a is declared as an A, A.a() is called.

Eric Jablow
  • 7,874
  • 2
  • 22
  • 29
1

Your method is not overridden method. you just try to put @Override annotation before your method in derived class. it will give you a compile time error. so java will not allow you to override static method.

1

While goblinjuice answer was accepted, I thought the example code could improved:

public class StaticTest {
    public static void main(String[] args) {
        A.print();
        B.print();
        System.out.println("-");

        A a = new A();
        B b = new B();
        a.print();
        b.print();
        System.out.println("-");

        A c = b;
        c.print();
    }
}

class A {
    public static void print() {
        System.out.println("A");
    }
}

class B extends A {
    public static void print() {
        System.out.println("B");
    }
}

Produces:

A
B
-
A
B
-
A

If B had overridden print() it would have write B on the final line.

David Newcomb
  • 10,639
  • 3
  • 49
  • 62
0

Static methods will called by its Class name so we don't need to create class object we just cal it with class name so we can't override static

for example

class AClass{
public static void test(){

 } 
}

class BClass extends AClass{
public static void test(){}

}

class CClass extends BClass{
public static void main(String args[]){

AClass aclass=new AClass();

aclass.test(); // its wrong because static method is called 
               // by its class name it can't accept object
}
}

we just call it

AClass.test();

means static class can't be overridden if it's overridden then how to cal it .

Stuart Siegler
  • 1,686
  • 4
  • 30
  • 38
0

Static members belong to class not to any objects. Therefore static methods cannot be overriden. Also overiding happens at run time therefore compiler will not complain.

Howeve, you can add @Override annotation to method. This will flag compiler error.

Prateek Kapoor
  • 947
  • 9
  • 18