Abstraction in Java with Example


In this article, we will learn the important core OOPS (object-oriented programming) concept - Abstraction.
Abstraction exposes to the user only those things that are relevant to them and hides the remainder of the details. In OOP terms, we say that an object should expose to the users only a set of high-level; operations, while the internal implementation of those operations is hidden.

Abstraction is achieved in Java via abstract classes and interfaces

Real-World Examples

Let's consider a real-life example: a man driving a car. The man knows what each pedal does and what the steering wheel does, but he doesn't know how these things are done internally by the car. He doesn't know about the inner mechanisms that empower these things. This is known as abstraction is.

Another real-world example, consider an ATM Machine; All are performing operations on the ATM machine like cash withdrawal, money transfer, retrieve mini-statement…etc. but we can't know internal details about ATM.

Implementation with Example

In Java, the abstraction is achieved by Interfaces and Abstract classes. We can achieve 100% abstraction using Interfaces.
Let's understand the Abstraction concept with Java programming examples.

Example 1: Employee, Contractor, and FullTimeEmployee Example 

In this example, we create an abstract Employee class and which contains the abstract calculateSalary() method. Let the subclasses extend the Employee class and implement a calculateSalary() method.

Let's create Contractor and FullTimeEmployee classes as we know that the salary structure for a contractor and full-time employees are different so let these classes override and implement a calculateSalary() method.

Let's write source code by looking into the above class diagram.
Step 1: Let's first create the superclass Employee. Note the usage of abstract keyword in this class definition. This marks the class to be abstract, which means it can not be instantiated directly. We define a method called calculateSalary() as an abstract method. This way you leave the implementation of this method to the inheritors of the Employee class.
public abstract class Employee {

    private String name;
    private int paymentPerHour;

    public Employee(String name, int paymentPerHour) {
        this.name = name;
        this.paymentPerHour = paymentPerHour;
    }

    public abstract int calculateSalary();
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPaymentPerHour() {
        return paymentPerHour;
    }
    public void setPaymentPerHour(int paymentPerHour) {
        this.paymentPerHour = paymentPerHour;
    }
}
Step 2: The Contractor class inherits all properties from its parent abstract Employee class but has to provide its own implementation to calculateSalary() method. In this case, we multiply the value of payment per hour with given working hours.
public class Contractor extends Employee {

    private int workingHours;
    public Contractor(String name, int paymentPerHour, int workingHours) {
        super(name, paymentPerHour);
        this.workingHours = workingHours;
    }
    @Override
    public int calculateSalary() {
        return getPaymentPerHour() * workingHours;
    }
}
Step 3: The FullTimeEmployee also has its own implementation of calculateSalary() method. In this case, we just multiply by a constant value of 8 hours.
public class FullTimeEmployee extends Employee {
    public FullTimeEmployee(String name, int paymentPerHour) {
        super(name, paymentPerHour);
    }
    @Override
    public int calculateSalary() {
        return getPaymentPerHour() * 8;
    }
}
Step 4: Let's create an AbstractionDemo class to test implementation of Abstraction with the below code:
public class AbstractionDemo {

    public static void main(String[] args) {

        Employee contractor = new Contractor("contractor", 10, 10);
        Employee fullTimeEmployee = new FullTimeEmployee("full time employee", 8);
        System.out.println(contractor.calculateSalary());
        System.out.println(fullTimeEmployee.calculateSalary());
    }
}

Example 2: Drawing Shapes Example

Consider the second example Shapes base type is “shape” and each shape has a color, size, and so on. From this, specific types of shapes are derived(inherited)-circle, square, triangle, and so on.
The areas for these shapes are different so make the area() method abstract and let the subclasses override and implement.
abstract class Shape {
    String color;

    // these are abstract methods
    abstract double area();

    public abstract String toString();

    // abstract class can have constructor
    public Shape(String color) {
        System.out.println("Shape constructor called");
        this.color = color;
    }

    // this is a concrete method
    public String getColor() {
        return color;
    }
}

class Circle extends Shape {
    double radius;

    public Circle(String color, double radius) {

        // calling Shape constructor
        super(color);
        System.out.println("Circle constructor called");
        this.radius = radius;
    }

    @Override
    double area() {
        return Math.PI * Math.pow(radius, 2);
    }

    @Override
    public String toString() {
        return "Circle color is " + super.color + "and area is : " + area();
    }

}

class Rectangle extends Shape {

    double length;
    double width;

    public Rectangle(String color, double length, double width) {
        // calling Shape constructor
        super(color);
        System.out.println("Rectangle constructor called");
        this.length = length;
        this.width = width;
    }

    @Override
    double area() {
        return length * width;
    }

    @Override
    public String toString() {
        return "Rectangle color is " + super.color + "and area is : " + area();
    }

}

public class AbstractionTest {
    public static void main(String[] args) {
        Shape s1 = new Circle("Red", 2.2);
        Shape s2 = new Rectangle("Yellow", 2, 4);

        System.out.println(s1.toString());
        System.out.println(s2.toString());
    }
}
Read more about Abstract class and abstract methods with examples at What is Abstract Class and Abstract Method in Java with Examples

GitHub Repository  

The source code of this article is available on my GitHub repository at OOPS Concepts Tutorial.
If you like this article then give a star to this repository.

Comments

  1. Examples are very good with explanation.

    ReplyDelete
  2. Very well described Abstraction concept with lots of examples. Other OOPS concepts are very well explained. Keep helping thanks

    ReplyDelete
  3. Very nicely explained OOPS concepts.

    ReplyDelete

Post a Comment

Leave Comment