Abstraction: Hiding the Complexity
Abstraction is the process of hiding the internal details of how something works and only showing the essential features to the user.
Think of a TV Remote. You know that pressing the "Power" button turns the TV on, but you don't need to understand the circuit board or the infrared signals inside to use it. That complexity is "abstracted" away.
In Java, we achieve abstraction using Abstract Classes and Interfaces.
1. Abstract Classes
An abstract class is a "half-finished" class. It can have regular methods, but it also has abstract methods—methods that have a name but no body { }.
- You cannot create an object of an abstract class (you can't do
new Animal()). - It serves strictly as a template for other classes.
abstract class Shape {
String color;
// Abstract method (No body! The child MUST implement this)
abstract double calculateArea();
// Regular method (The child inherits this normally)
void displayColor() {
System.out.println("The color is " + color);
}
}
2. Implementing the Abstract Class
When a class inherits from an abstract class, it must provide the code for all the abstract methods, or it must also be declared abstract.
class Circle extends Shape {
double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
double calculateArea() {
return Math.PI * Math.pow(radius, 2);
}
}
3. Why Use Abstraction?
- Security: You hide the complex or sensitive internal logic.
- Focus: You only define what an object should do, not how it does it.
- Consistency: It forces all subclasses to follow the same structure (every
ShapeMUST have acalculateAreamethod).
💻 Full Practical Example: The Appliance System
Copy this code to see how abstraction forces specific behaviors across different devices:
abstract class Appliance {
String brand;
Appliance(String brand) {
this.brand = brand;
}
// Every appliance turns on differently
abstract void turnOn();
void plugIn() {
System.out.println(brand + " is now plugged into the outlet.");
}
}
class Fan extends Appliance {
Fan(String brand) { super(brand); }
@Override
void turnOn() {
System.out.println("The fan blades start spinning...");
}
}
class Oven extends Appliance {
Oven(String brand) { super(brand); }
@Override
void turnOn() {
System.out.println("The heating elements are glowing orange...");
}
}
public class Main {
public static void main(String[] args) {
Appliance myFan = new Fan("Lasko");
Appliance myOven = new Oven("Samsung");
myFan.plugIn();
myFan.turnOn();
myOven.plugIn();
myOven.turnOn();
}
}