Abstraction in Java
A Simple Thought
Imagine driving a car. You don’t need to know how the engine works to use it, you just press the pedal and steer.
That’s exactly what abstraction does in programming. It hides the complex details of how something works and shows only what’s necessary.
Abstraction allows you to focus on what an object does, not how it does it.
It’s like giving simple controls for a complex system.
The Project: Payment System
You will create a program that simulates a payment process.
It will have an abstract class called Payment and two subclasses, CreditCardPayment and CashPayment, each providing its own version of a method called makePayment().
Your output will look like this:
1 2 3 4 5======================== PAYMENT SYSTEM Paying with Credit Card Paying with Cash ========================
Even though the payment process may be different, the interface remains the same, one method name, different actions.
The Concept: Abstraction
Abstraction in Java is achieved using abstract classes and interfaces.
An abstract class is a class that cannot be directly used to create objects. It can have both regular and abstract methods.
An abstract method is a method without a body, it only provides a declaration, and the subclasses must provide the details.
Here’s an example:
1 2 3abstract class Payment { abstract void makePayment(); }
This class defines the idea of a payment but does not specify how it happens.
Subclasses can then provide their own specific behavior:
1 2 3 4 5 6 7 8 9 10 11class CreditCardPayment extends Payment { void makePayment() { System.out.println("Paying with Credit Card"); } } class CashPayment extends Payment { void makePayment() { System.out.println("Paying with Cash"); } }
This way, you can design flexible systems where the details can change, but the interface stays the same.
Why This Matters
Abstraction simplifies complex systems by focusing on what’s important.
It allows you to:
- Hide unnecessary implementation details
- Provide a clear structure for your code
- Enable different parts of the program to work independently
For example, a payment system can support many types of payments, credit, cash, or online, without changing the overall design.
Each one just fills in its own details.
Let’s Build the Payment Program
Here’s the complete code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30abstract class Payment { abstract void makePayment(); } class CreditCardPayment extends Payment { void makePayment() { System.out.println(" Paying with Credit Card"); } } class CashPayment extends Payment { void makePayment() { System.out.println(" Paying with Cash"); } } public class PaymentSystem { public static void main(String[] args) { System.out.println("========================"); System.out.println(" PAYMENT SYSTEM"); Payment p1 = new CreditCardPayment(); Payment p2 = new CashPayment(); p1.makePayment(); p2.makePayment(); System.out.println("========================"); } }
When you run this program, both payment types share the same interface method, makePayment(), but provide different implementations.
This is the power of abstraction, it hides complexity behind a common structure.
How It Works
- The Payment class is declared as abstract and defines an abstract method makePayment().
- The CreditCardPayment and CashPayment classes extend Payment and give their own versions of makePayment().
- The main method creates objects of both subclasses using a Payment reference.
- Each object responds to the same method call differently.
This makes it easy to add new payment types later without changing the existing code.
Learn Together with AI
If you are using an AI Copilot, you can explore abstraction step by step.
Try this prompt:
“Write a Java program that uses an abstract class named Payment with subclasses for CreditCardPayment and CashPayment.”
Then add follow-ups like:
- “Add a third class for OnlinePayment.”
- “Use an array of Payment objects and loop through them.”
- “Explain what happens if we try to create an object from the abstract class.”
These tasks will help you understand how abstraction lets you hide complexity while keeping code organized.
Practice Challenge
Create a program that uses abstraction to represent animals.
There should be an abstract class called Animal with an abstract method makeSound().
Then create subclasses Dog and Cat that implement their own versions.
Your output should look like this:
1 2 3 4 5======================== ANIMAL SOUNDS Dog says Woof Cat says Meow ========================
Example Solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30abstract class Animal { abstract void makeSound(); } class Dog extends Animal { void makeSound() { System.out.println(" Dog says Woof"); } } class Cat extends Animal { void makeSound() { System.out.println(" Cat says Meow"); } } public class AnimalSound { public static void main(String[] args) { System.out.println("========================"); System.out.println(" ANIMAL SOUNDS"); Animal a1 = new Dog(); Animal a2 = new Cat(); a1.makeSound(); a2.makeSound(); System.out.println("========================"); } }
When you run this program, both animals respond to the same method call in different ways.
You don’t need to know how each one works inside, only that they make a sound.
Coming Up Next
You’ve now learned how abstraction simplifies complex systems by focusing on what matters most.
Next, you will learn about interfaces in Java, another form of abstraction that allows different classes to agree on a common set of actions.