July 4, 2022

Abstraction in Java - OOPS Concepts

In this post we’ll see the usage of OOPS concept Abstraction in Java.

What is Abstraction

Abstraction is one of the four fundamental principles of Object Oriented Programming along with inheritance, polymorphism and encapsulation.

Abstraction means hiding the complexity of the implementation and just exposing the essential features to the user. As an example you can take any electronics item where you interact with the product using buttons and switches to turn it on and off or increase and decrease the volume or speed. The real complexity, how that functionality is implemented is hidden from us.

There are many APIs in Java that can be shown as an example of abstraction in Java. A very well known one such API is JDBC which is used to connect to DB, execute queries and fetch results. As a developer we just know the methods of the API which are uniform, how these methods are implemented for different DBs is abstracted from us. We just add the required Driver for the used DB and use the same methods.

Abstraction in Java

If we have to hide the real implementation from the user that kind of abstraction in Java can be achieved through interfaces and abstract classes. By using interface the implementation is completely hidden, only the expected behavior is defined. With abstract class partial implementation can be provided.

Abstraction in Java – Interface example

Consider the following interface-
public interface User {
  int processFee(int numOfMonths);
}

Only the expected behavior is defined through a method in this interface, how it is implemented is abstracted.

There are two classes implementing this interface and providing method implementation as per type of User.

public class PlatinumUser implements User {
  final static int PLATINUM_PACKAGE = 1200;
  @Override
  public int processFee(int numOfMonths) {
    return PLATINUM_PACKAGE * numOfMonths;
  }
}
public class GoldUser implements User {
  final static int GOLD_PACKAGE = 700;
  @Override
  public int processFee(int numOfMonths) {
    return GOLD_PACKAGE * numOfMonths;
  }
}

You can run the implementation using the following class.

public class UserTest {
  public static void main(String[] args) {
    User user = new PlatinumUser();
    System.out.println("12 month fee for platinum user- " + user.processFee(12));
    user = new GoldUser();
    System.out.println("6 month fee for gold user- " + user.processFee(6));
  }
}
Output
12 month fee for platinum user- 14400
6 month fee for gold user- 4200

In the class using the User instance you can run the required implementation by just switching the reference. How those User implementing classes are implemented is abstracted.

Following image shows how user is abstracted from the real implementation.

Abstraction in Java

Abstraction in Java – Abstract class example

If we take the previous example there can be some common methods irrespective of the type of the user like getting name of the user, getting date of birth of the user where as calculation of the fee may differ.

In this scenario we can use an Abstract class keeping the common implementation there itself and abstracting the part that differ.

public abstract class User {
  private String name;
  private String designation;
  private int numOfMonths;
  public User(String name, String designation, int numOfMonths){
    this.name = name;
    this.designation = designation;
    this.numOfMonths = numOfMonths;
  }
  // abstract method
  public abstract int processFee();
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  public String getDesignation() {
    return designation;
  }
  public void setDesignation(String designation) {
    this.designation = designation;
  }
  public int getNumOfMonths() {
    return numOfMonths;
  }
  public void setNumOfMonths(int numOfMonths) {
    this.numOfMonths = numOfMonths;
  }	
}

In the abstract class processFee() method is abstract so it will be implemented by the classes extending the User class.

PlatinumUser.java
public class PlatinumUser extends User {
  final static int PLATINUM_PACKAGE = 1200;
  public PlatinumUser(String name, String designation, int numOfMonths){
    super(name, designation, numOfMonths);
  }

  public int processFee() {
    return PLATINUM_PACKAGE * getNumOfMonths();
  }
}
GoldUser.java
public class GoldUser extends User {
  final static int GOLD_PACKAGE = 700;
  public GoldUser(String name, String designation, int numOfMonths){
    super(name, designation, numOfMonths);
  }
  @Override
  public int processFee() {
    return GOLD_PACKAGE * getNumOfMonths();
  }
}

You can run the implementation using the following class.

public class UserTest {
  public static void main(String[] args) {
    User user = new PlatinumUser("Robbie", "CEO", 12);
    System.out.println("12 month fee " + user.processFee() + " for platinum user " + user.getName() + "("+user.getDesignation()+")" );
    user = new GoldUser("Alex", "Manager", 6);
    System.out.println("6 month fee " + user.processFee() + " for gold user " + user.getName() + "("+user.getDesignation()+")" );
  }
}
Output
12 month fee 14400 for platinum user Robbie(CEO)
6 month fee 4200 for gold user Alex(Manager)

In the class using the User instance you can run the required implementation by just switching the reference. For the methods getDesignation() and getName() common implementation from the User class is used. For the processFee() method which is abstracted, implementation from the extending classes is used.

That's all for the topic Abstraction in Java - OOPS Concepts. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment