Monday, 8 August 2016

Difference between Encapsulation and Abstraction in Java

Encapsulation and abstraction are two of the fundamental OOP concepts other two being polymorphism and inheritance.

Some times people do get confused between encapsulation and abstraction as both are hiding something. So in this post let's try to differentiate between these two concepts.

First let's try to define these two concepts to get some idea -
  • Encapsulation - Encapsulation means keeping together the implementation (code) and the data it manipulates (variables). Having proper encapsulation ensures that the code and data both are safe from misuse by outside entity. So, in a way Encapsulation is more about data hiding.
    It is a Java class which is the foundation of encapsulation in Java.

    Refer Encapsulation in Java to know more about encapsulation in Java.

  • Abstraction - Abstraction means hiding the complexity and only showing the essential features of the object. So in a way, abstraction means abstracting/hiding the real working and we, as a user, knowing only how to use.
    A very good example from Java would be - Java Database Connectivity (JDBC) API which provides universal data access from the Java programming language. Using the JDBC API, we can access virtually any data source without knowing how the driver for that particular data source is implemented. All we have is an API with a given set of methods. 
    PreparedStatement pstmt = conn.prepareStatement(SQL);
    

    While writing this line we don't bother how connection or prepareStatement is implemented in Oracle, SQLServer, DB2 or MySQL for us as a user those details are abstracted and we just know how to use JDBC API to interact with DBs. 

    Abstraction in Java is achieved through interface and abstract class.

      Refer Abstraction in Java to know more about abstraction in Java.

Hope you have got some idea now about these two terms, so let's see the differences between these terms.

Difference between Encapsulation and Abstraction

  1. Encapsulation is about keeping together the implementation and the data is manipulates. In a properly encapsulated Java class, method defines how member variables can be used. That access control to the methods and the variables is achieved through access modifiers (public, private, default & protected).
    Abstraction is about hiding the implementation and only giving the information about how to use it. Abstraction in Java is achieved through interfaces and abstract classes. 
  2. One of the benefit of Encapsulation is it helps in maintaining code that is changed frequently by keeping that in one place thus providing maintainability and flexibility. In fact that is one of the design principle Encapsulate what varies.
    Benefit of Abstraction is to provide a contract through interface or may be a bare skeletal implementation through Abstract class. Where as generalized implementations are provided based on that contract but user just sees the API.
      Any number of classes can implement an interface and each class is free to provide their own implementation. That's how using interfaces, Java fully utilizes "one interface, multiple methods" aspect of polymorphism. 

Let see an example for Encapsulation-

public class Employee {
    private String lastName;
    private String firstName;
    private String empId;
    private int age;
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getEmpId() {
        return empId;
    }
    public void setEmpId(String empId) {
        this.empId = empId;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    // method for getting full name
    public String getFullName(){
     return this.firstName + " " + this.lastName;
    }  
}
public class EmployeeTest {

 public static void main(String[] args) {
  Employee emp = new Employee();
  /*This line will give compiler error
  age field can't be used directly as it is private */
  // emp.age = 40;
     emp.setEmpId("E001");
     emp.setAge(40);
     emp.setFirstName("Ram");
     emp.setLastName("Chandra");
     System.out.println("Age- " + emp.getAge());
     System.out.println("Employee ID- " + emp.getEmpId());
     System.out.println("Full Name- " + emp.getFullName());

 }
}

Here we have a class called Employee and in the class there are public methods that provide access to the class’ fields (If you have noticed access modifier for all the fields is private). These methods for setting/getting the values of the fields are called setters and getters.

Any other class (in this example EmployeeTest) that wants to access the variables should access them through these getters and setters.
There is also one other method getFullName() in the same class which is using the fields of the class, that method can use the variables directly.

Let’s see an example for Abstraction -

Here we have an interface Ipayment with one method doPayment(). There are two implementing classes CashPayment and CreditCardPayment that provide implementation for cash payment and credit card payment respectively. But as a user all you need to know is that you have to call doPayment() method.

public interface IPayment {
 void doPayment(double amount);
}
public class CashPayment implements IPayment {

 @Override
 public void doPayment(double amount) {
  System.out.println("Cash payment " + amount);
  
 }
}
public class CreditCardPayment implements IPayment {

 @Override
 public void doPayment(double amount) {
  System.out.println("CreditCard payment " + amount);

 }

}
public class Payment {
 private static final String CASH = "CASH";
 private static final String CC = "CC";
 public static void main(String[] args) {
  Payment payment = new Payment();
  payment.executePayment(CASH, 34.45);
  payment.executePayment(CC, 34.45);
  

 }
 
 private void executePayment(String mode, double amount){
  IPayment payRef;
  // If payment is in CASH
  if(mode.equalsIgnoreCase(CASH)){
   payRef = new CashPayment();
   payRef.doPayment(amount);
   
  }
  // If payment is through credit card
  else if(mode.equalsIgnoreCase(CC)){
   payRef = new CreditCardPayment();
   payRef.doPayment(129.78);
  }
 }

}

In Payment class based on the mode of payment appropriate class is called. Of course there are better ways to do it using factory and encapsulating the logic in another class but here focus is more on knowing what is Abstraction.

That's all for this topic Difference between Encapsulation and Abstraction in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Association, Aggregation and Composition in Java
  2. Method overloading in Java
  3. Difference between abstract class and interface
  4. Access modifiers in Java
  5. Java OOP interview questions

You may also like -

>>>Go to Java Basics page

2 comments:

  1. Great information shared in this blog. Helps in gaining concepts about new information and concepts.Awsome information provided.Very useful for the beginners.
    Dotnet Training in Chennai

    ReplyDelete