2

It's not permitted to override and reduce visibility of inherited methods, but the point is you can't override a static method anyway:

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

So why is the second hide ok while the first one is not?

public class Base {

  public static void foo(){
      System.out.println("Base");
  }
}

hide1:

public class Sub extends Base {

  static void foo(){          //cannot reduce visibility error!
      System.out.println("Sub");
  }
}

hide2:

public class Sub extends Base {
  public static void foo(){   //OK
      System.out.println("Sub");
  }
}
A. Steiner
  • 31
  • 6
  • 2
    See [here](http://stackoverflow.com/questions/26963828/reducing-the-visibility-of-a-static-method) – Mena Feb 01 '16 at 17:00
  • @Mena can't find answer to "why" over there – A. Steiner Feb 01 '16 at 17:08
  • @A.Steiner because you are trying to **reduce** visibility of the `static` method. You cannot **reduce** visibility. If the method is `public` you can't change it to no modifier because you would be **reducing** the visibility. Check out the answer @Mena linked to and make sure to read the whole thing carefully... – brso05 Feb 01 '16 at 17:19
  • @A.Steiner for example if you remove the `public` modifier on `public static void foo(){` in your `Base` class both methods in the `Sub` class would compile because you wouldn't be **reducing** visibility...You couldn't have both in the subclass at the same time though you would have to put one in and then the other otherwise you would get a `duplicate method` compile error. – brso05 Feb 01 '16 at 17:22
  • thanks @brso05 I got it. so as I commented in the answers, why isn't it 'duplicate method' compile error instead? after all it's not an overriding.. – A. Steiner Feb 01 '16 at 17:34
  • @A.Steiner if you remove the `public` modifier like I said above you will get `duplicate method` compile error... – brso05 Feb 01 '16 at 17:35
  • @A.Steiner or just leave it like you have it but flip flop the order of the methods. Move `public static void foo(){ ` above `static void foo(){` in your `Sub` class and you will get `duplicate method` compile error. – brso05 Feb 01 '16 at 17:38
  • Sorry for mix-up, I edited to clarify the methods are two versions and not one after the other. – A. Steiner Feb 01 '16 at 17:41
  • @A.Steiner it is ok to "hide" the superclass method. A subclass can have the same `static` method as the superclass. The subclass method will "hide" the superclass method if it is called from the subclass. I will post an answer to help make it more clear... – brso05 Feb 01 '16 at 17:42
  • @A.Steiner check out my answer hopefully that makes sense... – brso05 Feb 01 '16 at 17:52
  • 1
    actually... such static methods are "overridden", in a sense. see [this answer](http://stackoverflow.com/questions/30875047/why-is-return-type-covariance-enforced-for-hidden-static-methods/30880161#30880161). The thing is, static methods were designed more dynamic than necessary; a mistake in retrospect. In any case, just for sanity's sake, to "hide" an otherwise accessible method is just creating confusions. If you add `class Sub2 extends Sub`, what does `Sub2.foo()` mean exactly? No such method? Access denied per Sub? Or Accessible per Base? – ZhongYu Feb 01 '16 at 18:19

2 Answers2

1

The reason is, you might want to give an instance of your subclass as an type of the superclass to a consumer. This consumer tries to run the (public) method he is used to run, since it's public, but you hid it with making it protected. To prevent this, this rule is introduced. (the problem is visibility, not static!). Although I have to admit, this reasoning doesn't completely apply to static methods, just when the consumer wants to directly have a subclass (as a subclass) like he was used to run the superclass.

ctst
  • 1,610
  • 1
  • 13
  • 28
  • The problem is it's not overriding, so by this reasoning isn't it suppose to be illegal overloading instead of visibility error? – A. Steiner Feb 01 '16 at 17:21
  • It is kind of overriding (called hiding) and certainly not overloading (there is no way to call the super-static and the sub-static with the same code, since you refer to them with the type). – ctst Feb 01 '16 at 17:25
  • @A.Steiner take a look at my comments... – brso05 Feb 01 '16 at 17:26
1

It is ok to hide a static superclass method in your subclass:

public class Base {
    public static void foo(){
        System.out.println("Base");
    }
}

public class Sub extends Base {
    static void foo(){          //cannot reduce visibility error!
        System.out.println("Sub");
    }
}

public class Sub1 extends Base {
    public static void foo(){   //OK
        System.out.println("Sub1");
    }
}

public class Main {
    public static void main(String[] args)
    {
        Base.foo();
        Sub1.foo();
    }
}

Output:

Base

Sub1

In Sub you are trying to reduce visibility (going from public to no modifier). In Sub1 you are not reducing visibility (going from public to public). That is why it compiles in Sub1 but not Sub. It is about the visibility of the method. It has nothing to do with overriding/hiding. (Hiding in this case since it is a static method).

If you try to run Sub.foo() in the main method without changing anything you will get this exception:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot reduce the visibility of the inherited method from Base

Here is a similar question and answer.

Community
  • 1
  • 1
brso05
  • 13,142
  • 2
  • 21
  • 40