Contents

Abstraction keyword

Abstraction

In Java, the abstract keyword is a non-access modifier applied to classes and methods, but not variables. It is primarily used to achieve abstraction, one of the core principles of Object-Oriented Programming (OOP). Below are the various contexts where the abstract keyword can be utilized in Java.

Characteristics of the abstract Keyword in Java

The abstract keyword is used to define abstract classes and methods. Here are its key characteristics:

  • Abstract classes cannot be instantiated: An abstract class is one that cannot be instantiated directly. It serves as a base class for other classes, which are responsible for providing concrete implementations of its abstract methods.
  • Abstract methods lack a body: An abstract method is declared using the abstract keyword and has no method body. It ends with a semicolon. Any class that extends an abstract class must provide implementations for all abstract methods.
  • Abstract classes can have both abstract and concrete methods: Along with abstract methods, an abstract class can also contain concrete methods with full implementations. These methods can be used by the abstract class itself or its subclasses.
  • Abstract classes can have constructors: While abstract classes cannot be instantiated, they can define constructors. These constructors are typically called during the instantiation of a concrete subclass.
  • Abstract classes can include instance variables: Abstract classes can declare instance variables, which can be accessed by both the abstract class and its subclasses.
  • Abstract classes can implement interfaces: An abstract class can implement interfaces and provide concrete implementations of the interface methods. However, the abstract class does not need to implement all methods immediately—this can be deferred to its subclasses.
Abstract Methods in Java

Abstract methods serve the purpose of declaring methods in a superclass without providing an implementation. Subclasses are responsible for implementing these methods. Abstract methods are often referred to as having “subclass responsibility.”

To declare an abstract method, use the following general syntax:

				
					abstract returnType methodName(parameterList);

				
			

Since no method body is provided, any class that extends an abstract class must implement all of the abstract methods.

Rules for Abstract Methods

Some important rules associated with abstract methods are:

  • Any class containing one or more abstract methods must also be declared abstract.
  • You cannot combine the abstract modifier with the following modifiers: final, native, synchronized, static, private, or strictfp.
Abstract Classes in Java

An abstract class is a class that has partial implementation, meaning it may have methods that lack concrete definitions. To declare a class abstract, use the following syntax:

				
					abstract class ClassName {
    // class body
}

				
			

Abstract classes cannot be instantiated directly, and any class that extends an abstract class must either implement all abstract methods or be declared abstract itself.

Example of Abstract Classes and Methods

Here’s an example that demonstrates the use of abstract classes and methods:

				
					// Abstract class representing a general vehicle
abstract class Vehicle {
    // Abstract method (no implementation)
    abstract void startEngine();
    
    // Concrete method
    void stopEngine() {
        System.out.println("Engine stopped.");
    }
}

// Concrete class representing a car
class Car extends Vehicle {
    // Providing implementation for the abstract method
    void startEngine() {
        System.out.println("Car engine started.");
    }
}

// Driver class to demonstrate abstract classes
public class Main {
    public static void main(String[] args) {
        Vehicle myCar = new Car();  // Vehicle reference, Car object
        myCar.startEngine();        // Output: Car engine started.
        myCar.stopEngine();         // Output: Engine stopped.
    }
}

				
			

Output:

				
					Car engine started.
Engine stopped.

				
			

Abstract Class in Java

Abstract Class in Java

In Java, an abstract class is defined using the abstract keyword. It is a class that cannot be instantiated on its own and may contain both abstract and concrete methods (methods with bodies). The abstract keyword can only be applied to classes and methods, not variables. In this article, we will explore the concept of abstract classes and their use in Java.

What is an Abstract Class?

An abstract class is a blueprint for other classes and cannot be used to create objects directly. It can only be subclassed, allowing other classes to inherit its properties. Declaring an abstract class in Java requires using the abstract keyword in its class definition. This approach allows for partial implementation of functionality, leaving subclasses to complete the abstract methods.

Illustration of Abstract Class

				
					abstract class Shape {
    int color;
    // Abstract method (no implementation)
    abstract void draw();
}

				
			
Important Points about Abstract Classes
  • Cannot Instantiate Abstract Classes: Instances of abstract classes cannot be created.
  • Constructors Are Allowed: Abstract classes can have constructors that are invoked when a subclass is instantiated.
  • No Abstract Methods Required: An abstract class can exist without any abstract methods.
  • Final Methods: Abstract classes can have final methods, but a method declared as abstract cannot be final, as this combination will result in an error.
  • Static Methods: Static methods can be defined in abstract classes.
  • Usage of Abstract Classes: Abstract classes can be used for both top-level (outer) and inner classes.
  • Incomplete Methods: If a subclass does not provide implementation for all abstract methods of a parent class, it must also be declared abstract.

Examples of Java Abstract Classes

1. Abstract Class with an Abstract Method: Here’s an example that demonstrates how an abstract class works in Java:

				
					// Abstract class
abstract class Vehicle {
    abstract void displayDetails();
}

// Class extending the abstract class
class Car extends Vehicle {
    void displayDetails() {
        String model = "Tesla";
        int year = 2024;
        double price = 55000.00;

        System.out.println("Model: " + model);
        System.out.println("Year: " + year);
        System.out.println("Price: $" + price);
    }
}

// Main class
public class Main {
    public static void main(String[] args) {
        Vehicle v = new Car();
        v.displayDetails();
    }
}

				
			

Output:

				
					Model: Tesla
Year: 2024
Price: $55000.0

				
			

Examples of Java Abstract Classes

2. Abstract Class with an Abstract Method : Here’s an example that demonstrates how an abstract class works in Java:

				
					// Abstract class
abstract class Course {
    Course() {
        System.out.println("Enrolled in the course");
    }
    abstract void courseSyllabus();
    void study() {
        System.out.println("Studying for exams!");
    }
}

// Subclass extending the abstract class
class ComputerScience extends Course {
    void courseSyllabus() {
        System.out.println("Topics: Data Structures, Algorithms, AI");
    }
}

// Main class
public class Main {
    public static void main(String[] args) {
        Course c = new ComputerScience();
        c.courseSyllabus();
        c.study();
    }
}

				
			

Output:

				
					Enrolled in the course
Topics: Data Structures, Algorithms, AI
Studying for exams!

				
			
Key Observations

Observation 1: Cannot Instantiate Abstract Classes

An abstract class cannot be instantiated directly, but you can create references of the abstract class type.

				
					// Abstract class
abstract class Animal {
    abstract void sound();
}

// Concrete class
class Dog extends Animal {
    void sound() {
        System.out.println("Bark");
    }
}

// Main class
public class Main {
    public static void main(String[] args) {
        // Animal a = new Animal(); // Error: Cannot instantiate the abstract class
        Animal a = new Dog();
        a.sound();
    }
}

				
			

Output:

				
					Bark

				
			

Observation 2: Abstract Class with Constructors

A constructor in an abstract class can be called when an instance of a subclass is created.

				
					abstract class Appliance {
    Appliance() {
        System.out.println("Appliance Constructor");
    }
    abstract void use();
}

class WashingMachine extends Appliance {
    WashingMachine() {
        System.out.println("Washing Machine Constructor");
    }
    void use() {
        System.out.println("Washing clothes");
    }
}

public class Main {
    public static void main(String[] args) {
        WashingMachine wm = new WashingMachine();
        wm.use();
    }
}

				
			

Output:

				
					Appliance Constructor
Washing Machine Constructor
Washing clothes

				
			

Observation 3: Abstract Class Without Abstract Methods

Abstract classes can exist without having abstract methods.

				
					abstract class Library {
    void borrowBook() {
        System.out.println("Borrowing a book");
    }
}

class CityLibrary extends Library {}

public class Main {
    public static void main(String[] args) {
        CityLibrary cl = new CityLibrary();
        cl.borrowBook();
    }
}

				
			

Output:

				
					Borrowing a book

				
			

Control Abstraction in Java with Examples

Before diving into control abstraction, let’s first understand the concept of abstraction.

Abstraction: Abstraction simplifies the complexity of a system by exposing only the essential features while hiding the intricate internal details. For example, when driving a car, the driver interacts with the steering wheel, pedals, and other controls, but the complex workings of the engine and electronics are abstracted away. The driver only needs to know how to operate the car, not how every internal mechanism functions.

Now, let’s explore an example of abstraction before delving into control abstraction:

				
					abstract class Person {
    abstract void displayDetails();
}

class Employee extends Person {
    void displayDetails() {
        String name = "John";
        int age = 30;
        double salary = 55000.50;

        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("Salary: $" + salary);
    }
}

class Main {
    public static void main(String[] args) {
        Person employee = new Employee();
        employee.displayDetails();
    }
}

				
			

Output:

				
					Name: John
Age: 30
Salary: $55000.5

				
			

In the above example, the details of an employee are abstracted through the Person class, and the specifics are implemented in the Employee class. Only essential information is shown to the user.

Types of Abstraction

There are two main types of abstraction:

1. Data Abstraction: This involves creating complex data types and exposing only essential operations.
2. Control Abstraction: This focuses on simplifying the program logic by removing unnecessary execution details and structuring the program into manageable parts.

Control Abstraction in Java

Control Abstraction in programming refers to the process of using higher-level operations and constructs (such as functions, loops, and conditional statements) to manage and simplify complex control flows. Instead of repeatedly writing out specific instructions, control abstraction encourages modular and reusable code that follows the DRY (Don’t Repeat Yourself) principle.

Key Features of Control Abstraction:
  • It promotes reusability by using methods and functions, thereby reducing code duplication.
  • Control abstraction bundles control statements into a single unit to make code easier to understand and manage.
  • It’s a fundamental feature of higher-level languages, including Java.
  • It focuses on how a task is achieved rather than the detailed steps involved in doing it.
  • It is often seen in structured programming through control structures like loops, conditionals, and function calls.

Example of Control Abstraction:

				
					// Abstract class
abstract class Vehicle {
    // Abstract method (does not have a body)
    public abstract void makeSound();

    // Regular method
    public void startEngine() {
        System.out.println("Engine starting...");
    }
}

// Subclass (inherit from Vehicle)
class Car extends Vehicle {
    public void makeSound() {
        // The body of makeSound() is provided here
        System.out.println("Car sound: Vroom Vroom");
    }
}

class Main {
    public static void main(String[] args) {
        // Create a Car object
        Car myCar = new Car();
        myCar.startEngine();  // Regular method
        myCar.makeSound();    // Abstract method implementation
    }
}

				
			

Output:

				
					Engine starting...
Car sound: Vroom Vroom

				
			

In this example:

  • startEngine() is a regular method defined in the Vehicle abstract class, and it’s used by any subclass.
  • makeSound() is an abstract method in Vehicle, and each subclass (like Car) must provide its own implementation of this method.

Key Steps of Control Flow:

1. The necessary resources are obtained.
2. The block of code is executed.
3. When control exits the block, resources are released or closed.

This structured approach ensures a clean flow of execution, making the program easier to read and maintain.

Difference Between Data Hiding and Abstraction in Java

Abstraction is the process of hiding the internal implementation and showcasing only the essential features or services. It allows the user to interact with the system without needing to understand its inner workings. This is accomplished through the use of abstract classes and interfaces in Java. Essentially, abstraction highlights only the necessary characteristics of an object, which distinguishes it from other objects, while suppressing non-essential details from the user.

Real-Life Example of Abstraction:

Consider an ATM machine. When you use an ATM, you see a graphical user interface (GUI) that displays services such as withdrawals, deposits, and checking balances. However, the internal mechanisms—such as how the transactions are processed—are hidden from the user.

Types of Abstraction

There are three main types of abstraction:

1. Procedural Abstraction: Involves a series of procedures (or functions) that are executed sequentially to achieve abstraction through the use of classes and methods.
2. Data Abstraction: Focuses on representing an object using a set of data while hiding its underlying implementation details.
3. Control Abstraction: Involves writing a program in such a way that the control flow details (such as loops, conditions, or method calls) are hidden, encapsulating the operations into higher-level functions or objects.

Advantages of Abstraction:
  • Security: Internal implementation details are hidden, which provides protection from unauthorized access.
  • Ease of Enhancement: Changes can be made to the internal system without affecting end users.
  • Flexibility: The system is easier to use for end users since they only interact with essential features.
  • Enhanced Application Quality: It helps in building more sophisticated and efficient applications by focusing on the most important aspects.
Implementation of Abstraction in Java

Abstraction is implemented using classes and interfaces, which represent only the significant traits and hide internal implementations. Here’s an example:

				
					// Abstract class representing a creature
abstract class Creature {

    // Abstract method hiding specific details
    abstract void numberOfLegs();
}

// A class representing an Elephant, inheriting from Creature
class Elephant extends Creature {

    // Implementing the abstract method
    void numberOfLegs() {
        System.out.println("The elephant has four legs.");
    }
}

// A class representing a Human, also inheriting from Creature
class Human extends Creature {

    // Implementing the abstract method
    public void numberOfLegs() {
        System.out.println("Humans have two legs.");
    }
}

public class Main {

    public static void main(String[] args) {
        // Creating Human object
        Human human = new Human();
        human.numberOfLegs();

        // Creating Elephant object
        Elephant elephant = new Elephant();
        elephant.numberOfLegs();
    }
}

				
			

Output:

				
					Humans have two legs.
The elephant has four legs
				
			

In this example, the Creature class is abstract and hides the internal details about the number of legs of different creatures. The concrete classes Elephant and Human provide specific implementations of the numberOfLegs method.

Data Hiding in Java

Data Hiding refers to the practice of hiding internal data from external access. This ensures that an object’s internal state cannot be directly accessed by other classes, maintaining security. Data hiding is usually achieved using access modifiers, such as private, which prevent external classes from directly accessing certain fields or methods.

Example of Data Hiding:

				
					class BankAccount {

    // Private variable for account balance
    private double accountBalance;

    // Getter method to access account balance securely
    public double getAccountBalance() {
        return accountBalance;
    }

    // Setter method to update account balance securely
    public void setAccountBalance(double accountBalance) {
        this.accountBalance = accountBalance;
    }
}

				
			

In this example, the accountBalance variable is hidden from other classes by using the private access modifier. External classes can only access or modify the account balance through the public getter and setter methods, ensuring data protection.

Key Differences Between Abstraction and Data Hiding:
  • Abstraction focuses on hiding unnecessary implementation details and showing only essential features to the user.
  • Data Hiding restricts access to the internal data of a class, ensuring that only certain methods can access or modify it.

Both concepts work together to promote encapsulation, ensuring the security and integrity of the system’s internal workings.