3

I would like to know: Why overriding method cannot have a more restrictive access modifier than method being overriden?

For example:

class Animal{
    public void eat(){
        System.out.println("Generic Animal Eating Generically");
    }
}

class Horse extends Animal{
    public void eat(){
        System.out.println("Horse eating hay, oats, and horse treats");
    }
}

In Horse class, why can't I write the code like this:

private void eat(){
    System.out.println("Horse eating hay, oats, and horse treats");
}

or

protected void eat(){
    System.out.println("Horse eating hay, oats, and horse treats");
}
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
AndroidTa
  • 79
  • 6
  • You should annotate an overridden function with `@Override ` – baao Jul 14 '17 at 07:01
  • because then you cannot call `Animal animal = new Horse(); animal.eat()` because `eat()` method would be private. But `Animal` class declared it as public. It's doesn't make sense. – Gondy Jul 14 '17 at 07:16

4 Answers4

7

Remember the principle Every Child is a Parent ?

Assume you have created an instance

Animal animal = new Horse();

when someone do animal.eat() what should happen now ?

Animal having an eat() method with sufficient permission and at the same time you have restricted the access of eat() in Horse to private meaning you can access that method only inside Horse. Bummer.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
4

It violates the polymorphism principle(subclass instance should be usable in place of a superclass instance)

Valentun
  • 1,661
  • 12
  • 23
0

This is one of main concepts of OOP the Polymorphism

When you extend a class you can't restrict visibiliy because if you create new instance of that child class there is a conceptual error.

Example:

Animal animal = new Horse();

In this case animal have method eat public but horse private, that not works. Creating instance of class that extend Animal i expect to have access to eat method.

Otherwise you can extend the method visibility in child class for example:

class Animal{
    protected void eat(){
        System.out.println("Generic Animal Eating Generically");
    }
}

class Horse extends Animal{
    public void eat(){
        System.out.println("Horse eating hay, oats, and horse treats");
    }
}
David Geirola
  • 616
  • 3
  • 17
0
  1. When you say Horse extends Animal, it means you are establishing a relationship that Horse IS A Animal

    Now assume if this was possible:

    class Animal{
        public void eat(){
            System.out.println("Generic Animal Eating Generically");
        }
    }
    
    class Horse extends Animal{
        private void eat(){
            System.out.println("Horse eating hay, oats, and horse treats");
        }
    }
    

    Suppose, there a third class where you are using this hierarchy.

     class B{
         Animal animalInstance = new Animal() ;
         animalInstance .eat();
         //other code that use this instance               
      } 
    

    Now, if you try to replace this animalInstance with Horse instance:

      private Horse horseInstance = new Horse();                     
      horseInstance .eat(); // Error! Horse doesn't expose this method to outside world!!
    

    Then this would result into a compile time error. And if Animal instance cannot be replaced by Horse instance, then Horse Isn't An Animal! You are violating IS A relationship.

  2. There is one more aspect to this. When you say method overriding, it is Runtime polymorphism. Means, at runtime, compiler will check, if child class has overriden this method, then apply child behavior, else parent behavior. In above case, when it will try to run Horse behavior, that will fail, because Horse is making it private.

    This kind of problems would not happen in the other case - where child override with less restrictive access modifier.

Hope this would clear your doubt.

adi
  • 304
  • 2
  • 11