Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Java allows increasing the visibility of protected methods in child class?

abstract class Base{
      protected abstract void a();
}

class Child extends Base{
      @Override
      public void a(){
          //why is this valid
      }
}

Why is that we can't reduce the visibility but can increase it?

Also I need to implement Template pattern in which the public methods visible can only be of base class.

Example:

abstract class Base{
      public void callA(){
      //do some important stuff
      a();
      }

      protected abstract void a();
}

class Child extends Base{
      @Override
      public void a(){
          //why is this valid
      }
}

Now if java allows to increase visibility then there are two methods visible publicly??

I know interface is one solution but is there some other way out???

like image 214
Narendra Pathai Avatar asked Oct 08 '12 11:10

Narendra Pathai


People also ask

Can we increase the visibility of the overridden method?

Asking for help, clarification, or responding to other answers. Making statements based on opinion; back them up with references or personal experience.

What is the purpose of protected methods?

Protecting a constructor prevents the users from creating the instance of the class, outside the package. During overriding, when a variable or method is protected, it can be overridden to other subclass using either a public or protected modifier only.

Can child class access private methods Java?

There is absolute no way this can be done. You cannot call a private method of a class from any other class(be it the extending class). It can only be accessed inside that class itself.

What determines the visibility of variables and methods?

By default, the variables and methods of a class are accessible to members of the class itself and to other classes in the same package. To borrow from C++ terminology, classes in the same package are friendly. We'll call this the default level of visibility.


2 Answers

Why decreasing visibility is not allowed is already explained in other responses (it would break the contract of the parent class).

But why it is allowed to increase the visibility of a method? First, it would not break any contract, so there is no reason to not allow it. It can be handy sometimes, when it makes sense in the child class for a method to not be protected.

Second, not allowing it could have the side effect of making impossible sometimes to extend a class and implement an interface at the same time:

interface Interface1 {
   public void method();
}

public class Parent {
   protected abstract void method();
}

public class Child extends Parent implements Interface1 {
   @Override
   public void method() {
   }
   //This would be impossible if the visibility of method() in class Parent could not be increased.
}

About your second question, you can do nothing about it. You have to trust that the person who implements the child class doesn't do anything that breaks your implementation. Even if java wouldn't allow to increase visibility, that would still not fix your problem, because a public method with a different name could be created that calls the abstract method:

class Child extends Base{
      @Override
      protected void a(){

      }

      public void a2() {
           a(); //This would have the same problems that allowing to increase the visibility.
      }
}
like image 185
Pablo Avatar answered Sep 18 '22 03:09

Pablo


If the base class makes a promise regarding visibility, then the subclass cannot break that promise and still satisfy the Liskov substitution principle. You can't use a subclass in any situation where the promised method is exposed if that promise is broken.

The subclass IS-A base class. If the base class exposes a method, so must the subclass.

There's no way out in Java or C++. I'd guess the same is true in C#.

like image 36
duffymo Avatar answered Sep 19 '22 03:09

duffymo