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

Saturday, April 8, 2017

Overloading - Argument Lists

In this section we will talk about the argument lists in method overloading. Method overloading can be achieved if method signature is different. It can be different number of parameters, data types or sequence but return type doesn't matter. In our example we created a program for some simple calculation.

method 1: two parameters (two int)
method 2: three parameters (three int)
method 3: two parameters (one int, one float)
method 4: two parameters (one int, one float) but in different sequence

class A
{
   public static int method1(int x, int y)  {return x+y;}
   public static int method2(int x, int y, int z)  {return x+y+z;}
   public static float method3(int x, float y)  {return y-x;}
   public static float method4(float x, int y)  {return x-y;}
}

public class OverloadingTest1
{
   public static void main(String args[])
   {
  System.out.println("method 1: "+A.method1(5,9));
  System.out.println("method 2: "+A.method2(4,7,2));
  System.out.println("method 3: "+A.method3(5,14.2f));
  System.out.println("method 4: "+A.method4(7.8f,2));
   }
}

Result:
method 1: 14
method 2: 13
method 3: 9.2
method 4: 5.8

Polymorphism Concepts

Polymorphism is one of main four concepts in Java. The word polymorphism means many forms. That means it has many different kinds of forms. There are two types of polymorphism: dynamic and static. Actually it has many ways to describe polymorphism but in fact it refers to method overridding and overloading concepts.

What is method overriding and overloading ?

Method overridding: There are two methods with same name as they share same method signature. Method signature includes data types, number, sequence and return type. Technically speaking method overridding can have different return types but it should obey some rules that return type of overridding method should be the same or a subtype of its overridden method in parent class.

Method overloading: Method overloading is similar to method overridding. It has same method name but different method signature. Return type doesn't matter for method overloading, It can be same or different.

Polymorphism Comparison


Below list summarizes differences between method overidding and overloading.

Argument list
Overriding: Same method name as well as same data type, number, sequence
Overloading: Same method name but different method signature (data type, number, sequence)

Return type
Overriding: Same or compatible as subtype
Overloading: Same or different (doesn't matter)

Polymorphism type
Overridding: Runtime, object type (not reference variable type) determines which methods should be overridden at runtime
Overloading: Compile time

Binding
Overridding: dynamic => same method signatures make compiler confuse
Overloading: static => private, static and final are restricted to local class scope

Applies to
Overridding: inherited and abstract methods, static methods can be redeclared in subclass but nothing to do with static method in parent class
Overloading: in the same class or subclass, constructor, private, static and final methods

Exceptions
Overridding: can throw any unchecked exceptions. However, the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method.
Overloading: can throw different exceptions

Performance
Overridding: Because done by runtime
Overloading: Better

Class Requirement
Overridding: Two classes (superclass and subclass)
Overloading: within one class

Access Level
Overridding: cannot be restrictive than overridden method of parent class
Overloading: can be restrictive or more accessible

Encapsulation

Encapsulation in Java is the mechanism of wrapping data (variables) and code acting on data (methods) together as a single unit. The implementation details are hidden from outside classes and it can be accessed via public methods of setter and getter defined by class. Outside classes are unable to access private data members (variables and methods) directly and it is so called data hiding.

Advantages: improved flexibility, reusability and maintainability. Whenever there is changes in method behavior we only need to change the method instead of relevant outside classes.

To achieve encapsulation in Java:
-Declare the variables of a class as private.
-Provide public setter and getter methods to modify and view the variables values.

class Vehicle
{
  private int speed;
  private String color;
  
  public void setSpeed(int s)
  { speed = s; }
  
  public void setColor(String c)
  { color = c; }
  
  public int getSpeed()
  {return speed;}
  
  public String getColor()
  {return color;}
}

public class VehicleTest
{
  public static void main(String args[])
  {
Vehicle v = new Vehicle();
v.setColor("blue");
v.setSpeed(300);
  System.out.println("Speed: "+v.getSpeed());
System.out.println("Color: "+v.getColor());
  }
}

Result:
Speed: 300
Color: blue

Hybrid Inheritance

Hybrid Inheritance is the combination of single and multiple inheritance. By using interface it can achieve multiple inheritance as well.


Abstraction vs Interface

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