Which access modifier, in an abstract class, do I have to use for a method, so the subclasses can decide whether it should be public or not? Is it possible to "override" a modifier in Java or not?
public abstract class A { ??? void method(); } public class B extends A { @Override public void method(){ // TODO } } public class C extends B { @Override private void method(){ // TODO } }
I know that there will be a problem with static binding, if someone calls:
// Will work A foo = new B() foo.method(); // Compiler ? A foo = new C(); foo.method();
But maybe there is another way. How I can achieve that?
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides.
Method Overriding with Access Modifiers There is Only one rule while doing Method overriding with Access modifiers i.e. If you are overriding any method, overridden method (i.e. declared in subclass) must not be more restrictive. Access modifier restrictions in decreasing order: private.
An override method is a new implementation of a member that is inherited from a base class. The overridden base method must be virtual, abstract, or override. Here the base class is inherited in the derived class and the method gfg() which has the same signature in both the classes, is overridden.
Yes. It is possible for overridden methods to have different return type . But the limitations are that the overridden method must have a return type that is more specific type of the return type of the actual method.
It is possible to relax the restriction, but not to make it more restrictive:
public abstract class A { protected void method(); } public class B extends A { @Override public void method(){ // OK } } public class C extends A { @Override private void method(){ // not allowed } }
Making the original method private
won't work either, since such method isn't visible in subclasses and therefore cannot be overriden.
I would recommend using interface
s to selectively expose or hide the method:
public interface WithMethod { // other methods void method(); } public interface WithoutMethod { // other methods // no 'method()' } public abstract class A { protected void method(); } public class B extends A implements WithMethod { @Override public void method(){ //TODO } } public class C extends B implements WithoutMethod { // no 'method()' }
... then only work with the instances through the interfaces.
When overriding methods, you can only change the modifier to a wider one, not vice versa. For example this code would be valid:
public abstract class A { protected void method(); } public class B extends A { @Override public void method() { } }
However, if you try to narrow down the visibility, you'd get a compile-time error:
public abstract class A { protected void method(); } public class B extends A { @Override private void method() {} }
For your case, I'd suggest to make C
not implementing A
, as A
's abstraction implies that there's a non-private method()
:
public class C { private void method(){ //TODO } }
Another option is to make the method()
implementation in C
throwing a RuntimeException:
public class C extends A { @Override public void method(){ throw new UnsupportedOperationException("C doesn't support callbacks to method()"); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With