Showing posts with label overriding. Show all posts
Showing posts with label overriding. Show all posts

Sunday, April 9, 2017

Overriding - Access Level

When method is overriding in subclass the access modifier should be taken into consideration otherwise there will be compilation error. The rule is that access level of overriding methods should not be restrictive than the overridden method in parent class.

In this example we have method eat() with public access modifier but subclass overriding version defined with protected which is restrictive than public. Method sleep() with protected access modifier but subclass overriding version defined with private which is also restrictive than protected. So it violates to the overriding rule.

class X
{
  public void eat() {}
  protected void sleep() {}
}

class Y extends X
{
  protected void eat() {}
  private void sleep() {}
}

public class OverridingAccessTest
{
  public static void main(String args[])
  {
  
  }
}

Results:
OverridingAccessTest.java:9: error: eat() in Y cannot override eat() in X
  protected void eat() {}
                 ^
  attempting to assign weaker access privileges; was public

OverridingAccessTest.java:10: error: sleep() in Y cannot override sleep() in X
  private void sleep() {}
               ^
  attempting to assign weaker access privileges; was protected
2 errors

Overriding - Return Types

Method Overriding happens when method signatures are the same for subclass and its superclass. Return types should be either the same or return type of subclass is compatible with its superclass. Compatible means return type of overriding method is subtype of its overridden method.

Dog is subclass of Canine. Canine has two methods and Dog inherits these two methods. You can see methodA has same method signature as well as return type. For method getType the return type is Dog and Canine. Because Dog is subclass of Canine. So overriding method can use subclass as return type. Otherwise it raises compilation error of "return type is not compatible with....".

class Canine
{
  public Canine getType(Canine d)
  {
    return d;
  }
  
  public float methodA(int a, int b, float c)
  {
 return c*c;
  }
}

class Dog extends Canine
{
  public Dog getType(Dog d)
  {
    return d;
  }

  public float methodA(int a, int b, float c)
  {
 return a*b;
  }
}

public class OverriddingTest1
{
  public static void main(String args[])
  {
     Canine c1 = new Canine();
     Dog d1 = new Dog();
     Canine c2 = new Dog();
     System.out.println("Canine c1: "+c1.getType(c1).getClass());
     System.out.println("Dog d1: "+d1.getType(d1).getClass());
     System.out.println("Dog c2: "+c2.getType(c2).getClass());

     System.out.println("\nd1: "+d1.methodA(4,8,2.2f));
     System.out.println("d1: "+d1.methodA(5,9,3.2f));
  }
}

Results:
Canine c1: class Canine
Dog d1: class Dog
Dog c2: class Dog

d1: 32.0
d1: 45.0

Abstraction vs Interface

Abstract Interface method abstract and concrete abstract only, support default and static method ...