javaoverridingreturn-type

Why can't we reduce visibility while method overriding (specially public to default)



This is a very basic concept that we can't reduce the visibility of a method while overriding. But I want to understand why?
class Parent{
  public void getData(){
   System.out.println("Parent GetData")
  }
}
class Child{
  void getData(){
   System.out.println("Parent GetData")
  }
}
public class OverridingDemo{
 public static void main(String[] args)
 {
  Parent p = new Child();
  p.getData(); // Error
 }
}

Here we have changed the return type to default which allows accessibility to same package. Then why is it not allowed to change the return type to default?
I do understand that if it was private or protected then in that case it cant be accessed but why not for default?
Yes, there are already a lot of threads available but I wasn't able to understand the concept clearly.


Solution

  • It's about type safety and polimorphism.

    It can't be done, precisely because the extending classes can be polimorphically passed everywhere the extended class can. Thus, the caller of extended class (say com.yadvendra.vehicles.Car with public method int speed()) calls the public method of the class. But the instance variable holding the class can be either the extended class (Car), or the extending class (say RaceCar). Because of polymorphism, the caller of Car.speed() should be able to call RaceCar.speed() without knowing the exact type - the compiler just needs to make sure that Car is substituble to RaceCar. That's polymorphism.

    The caller of Car.speed() has the right to call .speed() method, since it's public. Have you lowered the visibility of RaceCar.speed(), then the caller would receive RaceCar of which speed() is protected (or default). And it would appear that the caller can't call the method. So the compiler doesn't allow that.

    However, the fact that you try to change the visibility of the method on the extending class points to a deeper issue. It would seem that you want to extend the class, but not its interface (since you'd like to hide some of the methods). That seems like a strong reason to believe that your Child class should probably not extended Parent (because it wouldn't be substituble for Parent anyway).