Sunday, April 9, 2017

Abstraction vs Interface

Abstract Interface
method abstract and concrete abstract only, support default and static method
multiple inheritance no (extend one class) yes (extends multiple interfaces)
variables final, non-final, static and non-static
default: declared as public, static, final
static, final
implementation provides interface implementation doesn't provide abstract class implementation
constructor allowed not allowed
keyword abstract (implicit: public, abstract) interface
inheritance implements multiple interfaces but
can extend one class
extends multiple interfaces

Interface

An interface in Java is blueprint of a class. It can achieve abstraction and provides multiple inheritances.

Interface is similar to abstraction class but interface is purely abstract. So it is blueprint of a class instead of object instantiation. Below illustrate interface characteristics in Java.

Interface

  • Interface can have only abstract methods. Since Java 8, it can have default and static methods also
  • Interface supports multiple inheritance (An interface can extend multiple interfaces)
  • Interface has only static and final variables.
    [By default variables are declared as public, static and final]
  • Interface can't provide the implementation of abstract class
  • Constructor is not allowed in Interface
    [There is only static fields in interface that doesn't need to be initialized during object creation in subclass and the method of interface has to provide actual implementation in subclass. So there is no need of constructor in interface]
    [During the object creation of subclass, the parent constructor is called. But if there will be more than one interface implemented then a conflict will occur during call of interface constructor as to which interface's constructor will call first]
  • The interface keyword is used to declare interface
    [By default interface is implicitly public and abstract]

Abstraction

In simple word abstraction is the process of showing relevant functionalities to users and hide the implementation details. Just like users only focus on what the object does instead of how to do it. There are two ways to achieve abstraction in Java - Abstract class and Interface.

Abstract Class

  • Abstract classes may or may not contain abstract methods. It can contain abstract or concrete methods. That's why it is partially abstract
  • The class must be declared abstract if a class has at least one abstract method
  • It cannot be instantiated if a class is declared abstract
  • If subclass is inherited from abstract class it must provide all abstract methods implementation inside it. If subclass is also abstract it can include abstract methods
  • Abstract class doesn't support multiple inheritance. (it can extends abstract or concrete class)
  • Constructor is allowed in abstract class
  • Abstract class can have final, non-final, static and non-static variables
  • Abstract class can provide the implementation of interface



Overloading - Access Level

In the scenario of method overloading. The access modifier of methods can be less restrictive or more accessible. There are two methods eat() and sleep(). One is public and other is protected in class P. You see there are restrictive and more accessible version of methods.

class P
{
  public void eat() {}
  protected void eat(int a) {}
 
  protected void sleep() {}
  private void sleep(String s) {}
  public void sleep(String s, float x) {}
 
}

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

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 ...