🎉 Special Offer !    Code: GET300OFF    Flat ₹300 OFF on every Java Course
Grab Deal 🚀

Abstraction in Java  


Introduction
  • Abstraction is a concept of :
    • hiding internal implementation details and showing only the essential features to the user.
  • Real World Example
    • When you drive a car, you only need to know how to operate the steering wheel, pedals and gear shift. You don't need to understand how the engine works or how the brakes are designed.
      James Gosling
  • How to achieve Abstraction :-
    • We can achieve Abstraction by two ways:
      • Using Abstract Classes
      • Using Interfaces

Abstract Methods :-
  • Introduction
    • An abstract method is a method that is declared without an implementation (no method body).
    • It only provides the method signature and forces subclasses to provide the actual implementation.
    • Declared using the abstract keyword.
  • Syntax & Example :
    • Syntax : abstract returnType methodName(parameters);
    • Example : abstract void makeSound(); // Abstract method – no body
  • Rules of Abstract Method :
    • No method body – ends with a semicolon (;).
    • Must be declared inside an abstract class or interface.
    • A class that contains an abstract method must be declared abstract.
    • Abstract methods must be overridden by subclasses, unless the subclass is also abstract.
    • Cannot be private, static or final — because it must be overridden.
Abstract Class :-
  • Introduction
    • An abstract class in Java is a class that is declared using the abstract keyword.
    • It can contain a mix of abstract methods (without body) and concrete methods (with body).
    • It cannot be instantiated (you cannot create objects of it).
  • Syntax & Example :
    • Syntax:
      abstract class ClassName
      {
          // abstract method
          abstract void makeSound();
      
          // concrete method
          void sleep()
          {
              System.out.println("Sleeping...");
          }
      }
    • Example:
      abstract class Car
      {
          // Abstract method (must be implemented by subclasses)
          abstract void startEngine();
      
          // Concrete method
          void fuelType()
          {
              System.out.println("This car uses petrol or diesel.");
          }
      }
      class Sedan extends Car
      {
          @Override
          void startEngine()
          {
              System.out.println("Sedan engine started with key ignition.");
          }
      }
  • Rules of Abstract Class :
    • Must be declared using the abstract keyword.
    • Can contain both abstract and concrete methods.
    • Cannot be instantiated directly.
    • Subclass must override all abstract methods or be declared abstract itself.
    • Can have constructors, static methods and final methods.
    • Can extend another class and implement interfaces.

Program Without Abstraction
  • class Car
    {
        int no_of_tyres = 4;
    
        void displayTyres()
        {
            System.out.println("Car has " + no_of_tyres + " tyres.");
        }
    
        void start()
        {
            System.out.println("Car starts with a key ignition.");
        }
    }
    
    // Scooter class without abstraction
    class Scooter
    {
        int no_of_tyres = 2;
    
        void displayTyres()
        {
            System.out.println("Scooter has " + no_of_tyres + " tyres.");
        }
    
        void start()
        {
            System.out.println("Scooter starts with a kick or self-start.");
        }
    }
    
    // Main class to run the program
    public class MainApp
    {
        public static void main(String[] args)
        {
            Car myCar = new Car();
            myCar.displayTyres();
            myCar.start();
    
            System.out.println();
    
            Scooter myScooter = new Scooter();
            myScooter.displayTyres();
            myScooter.start();
        }
    }
    Output:
    Car has 4 tyres.
    Car starts with a key ignition.
    
    Scooter has 2 tyres.
    Scooter starts with a kick or self-start.
Disadvantages of Not Using Abstraction
  1. No Polymorphism:
    • We can’t use a common parent reference to refer to multiple types of vehicles.
    • Example:
      Vehicle vehicle = new Car(); // Not possible, because there is no common Vehicle type
    • This limits flexibility and makes it hard to treat Car and Scooter uniformly.
  2. Code Duplication:
    • Common logic like displayTyres() is repeated in every class (Car, Scooter, etc.).
    • In a larger system, this leads to duplicate code, harder maintenance, and higher chances of bugs.
  3. No Method Enforcement:
    • There is no guarantee that all vehicle-related classes will implement essential methods like start().
    • A developer might forget to add a critical method in a new class like Bike, leading to incomplete functionality.
  4. Poor Scalability:
    • As the project grows and more vehicle types are added, maintaining consistency becomes harder.
    • Any change in shared logic (e.g., tyre display format) needs to be updated in every individual class, increasing maintenance overhead.
  5. No Common Structure or Contract:
    • Without a common abstract class or interface, there’s no standard structure that all vehicle classes must follow.
    • This leads to inconsistent design and makes collaboration or team development harder.
Program Using Abstraction
  • // Abstract class used to remove code duplication and enforce method structure
    abstract class Vehicle
    {
        int no_of_tyres;
    
        // Common method to avoid duplication (removes disadvantage #2)
        void displayTyres()
        {
            System.out.println("This vehicle has " + no_of_tyres + " tyres.");
        }
    
        // Abstract method to enforce implementation in all subclasses (removes disadvantage #3)
        abstract void start();
    }
    
    // Car class extends abstract class and provides its own implementation
    class Car extends Vehicle
    {
        Car()
        {
            no_of_tyres = 4;
        }
    
        // Required by abstract class - enforces structure (removes disadvantage #3)
        @Override
        void start()
        {
            System.out.println("Car starts with key ignition.");
        }
    }
    
    // Scooter class also extends abstract class
    class Scooter extends Vehicle
    {
        Scooter()
        {
            no_of_tyres = 2;
        }
    
        @Override
        void start()
        {
            System.out.println("Scooter starts with kick or self-start.");
        }
    }
    
    // Main class to test polymorphism and abstraction
    public class Main
    {
        public static void main(String[] args)
        {
            // Using polymorphism (removes disadvantage #1)
            Vehicle myVehicle1 = new Car();
            myVehicle1.displayTyres();
            myVehicle1.start();
    
            System.out.println();
    
            Vehicle myVehicle2 = new Scooter();
            myVehicle2.displayTyres();
            myVehicle2.start();
    
            // Easier to scale and add new vehicle types consistently (removes disadvantage #4)
        }
    }
    Output:
    This vehicle has 4 tyres.
    Car starts with key ignition.
    
    This vehicle has 2 tyres.
    Scooter starts with kick or self-start.