java
- IntroductionInstallation and SetupJava Syntax and StructureRunning Your First ProgramJava VariablesData Types in JavaOperators in JavaJava Input and OutputControl StatementsLoops in JavaMethods in Java (Functions)Arrays in JavaString Handling in JavaOOPS Concept in JavaClasses and ObjectsConstructor and Constructor Overloadingthis KeywordStatic MembersInheritanceAggregation in JavaMethod OverloadingMethod Overridingsuper KeywordFinal Keyword with Class, Method, and VariablesAccess Modifiers in javaEncapsulation in Java Polymorphism in JavaAbstraction in JavaAbstract ClassesInterfaces in JavaDifference between Abstract Class and Interface Nested and Inner Classes Exception HandlingJava PackagesWrapper Classes and AutoboxingJava Collections FrameworkFile Handling in JavaMultithreadingBasics of Java Memory Management and Garbage CollectionJava JDBC
Abstract Classes in Java – Full Tutorial for Beginners
Last Updated on: 21st Nov 2025 17:18:36 PM
Welcome to the most beginner-friendly and complete tutorial on Abstract Classes in Java!
By the end of this guide, you’ll fully understand what abstract classes are, why we need them, and how to use them with real-life examples you’ll never forget.
Let’s start!
What is an Abstract Class in Java?
An abstract class is a class that cannot be instantiated (you cannot create objects of it directly).
It is meant to be (inherited by other classes) a blueprint or template for other classes.
It can contain:
✔ Abstract methods (methods without body)
✔ Normal methods (with body)
✔ Variables
✔ Constructors
✔ Static methods
Why Do We Use Abstract Classes?
To provide a common base for all child classes
If multiple classes share common logic, an abstract class helps avoid duplicate code.
To enforce a rule
Child classes must implement abstract methods → ensures consistency.
To achieve abstraction
Abstract class can hide internal logic & expose only important features.
You declare it using the keyword: abstract
abstract class ClassName {
// fields, methods, abstract methods
}
Imagine you're building a Mobile App for a Zoo
You have different animals:
-
Lion
-
Elephant
-
Parrot
-
Penguin
All animals have some common things:
-
They eat
-
They sleep
-
They make a sound
But how they make sound is different:
-
Lion → Roars
Parrot → Talks
Penguin → Honks
So, you want to force every animal to have a makeSound() method,
but you don’t know how it will sound — that depends on the animal!
This is exactly where abstract classes shine!
Real-Life Example: Zoo Management System
// Abstract Class (Template for all animals)
abstract class Animal {
String name;
int age;
// Constructor
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// Normal method (common for all animals)
void eat() {
System.out.println(name + " is eating...");
}
void sleep() {
System.out.println(name + " is sleeping... Zzz");
}
// Abstract method (MUST be implemented by child classes)
abstract void makeSound();
}
// Concrete classes (Actual animals)
class Lion extends Animal {
public Lion(String name, int age) {
super(name, age); // Call parent constructor
}
@Override
void makeSound() {
System.out.println(name + " says: ROARRR!");
}
}
class Parrot extends Animal {
public Parrot(String name, int age) {
super(name, age);
}
@Override
void makeSound() {
System.out.println(name + " says: Hello! Polly wants a cracker!");
}
}
class Penguin extends Animal {
public Penguin(String name, int age) {
super(name, age);
}
@Override
void makeSound() {
System.out.println(name + " says: Honk! Honk!");
}
}
// Main class to test
public class ZooApp {
public static void main(String[] args) {
Animal lion = new Lion("Simba", 5);
Animal parrot = new Parrot("Coco", 2);
Animal penguin = new Penguin("Pingu", 3);
lion.eat(); // Simba is eating...
lion.makeSound(); // Simba says: ROARRR!
parrot.sleep(); // Coco is sleeping... Zzz
parrot.makeSound(); // Coco says: Hello! Polly wants a cracker!
penguin.makeSound(); // Pingu says: Honk! Honk!
}
}
Output:
Simba is eating...
Simba says: ROARRR!
Coco is sleeping... Zzz
Coco says: Hello! Polly wants a cracker!
Pingu says: Honk! Honk!
Perfect!
The Animal class defines what every animal must do (makeSound()),
but each animal decides how to do it.
This is Abstraction in Action!
Rules of Abstract Classes
| Rule | Explanation |
|---|---|
| Cannot create object | ✔ new AbstractClass() ❌ |
| Can have both abstract + normal methods | ✔ Allowed |
| Must be inherited | ✔ Child class uses extends |
| Child must implement abstract methods | ✔ Mandatory |
| Can have constructors | ✔ But cannot instantiate |
| Supports all access modifiers | public, private, protected |
| Can contain variables | ✔ instance, static, final |
Real Life Example: Online Payment
All payment gateways (Paytm, PhonePe, Google Pay) must follow the same rules:
-
Validate payment
-
Process payment
-
Send notification
But the internal logic differs.
Abstract Class Example
abstract class Payment {
abstract void validate();
abstract void pay();
void receipt() {
System.out.println("Payment receipt sent to email.");
}
}
class GooglePay extends Payment {
void validate() {
System.out.println("GooglePay validation done.");
}
void pay() {
System.out.println("Payment done via GooglePay.");
}
}
class Paytm extends Payment {
void validate() {
System.out.println("Paytm validation done.");
}
void pay() {
System.out.println("Payment done via Paytm.");
}
}
public class Main {
public static void main(String[] args) {
Payment p = new GooglePay();
p.validate();
p.pay();
p.receipt();
}
}
Output
GooglePay validation done.
Payment done via GooglePay.
Payment receipt sent to email.
Why abstract class?
Because all payment apps must follow the same structure, but implementation differs.
Another Real-Life Example: Bank System
abstract class Bank {
String bankName;
Bank(String name) {
this.bankName = name;
}
// Common method
void displayBankInfo() {
System.out.println("Welcome to " + bankName);
}
// Abstract methods – every bank has different rates
abstract double getInterestRate();
abstract void openAccount();
}
class SBI extends Bank {
SBI() {
super("State Bank of India");
}
@Override
double getInterestRate() {
return 7.0;
}
@Override
void openAccount() {
System.out.println("SBI Account opened with zero balance!");
}
}
class HDFC extends Bank {
HDFC() {
super("HDFC Bank");
}
@Override
double getInterestRate() {
return 8.5;
}
@Override
void openAccount() {
System.out.println("HDFC Account requires minimum ₹5000");
}
}
public class BankTest {
public static void main(String[] args) {
Bank sbi = new SBI();
Bank hdfc = new HDFC();
sbi.displayBankInfo(); // Welcome to State Bank of India
System.out.println("Interest Rate: " + sbi.getInterestRate() + "%");
hdfc.displayBankInfo(); // Welcome to HDFC Bank
hdfc.openAccount(); // HDFC Account requires minimum ₹5000
}
}
Perfect for interviews! – Banks have common features, but rules differ!
Why Abstract Class = 0–100% Abstraction?
-
It may contain 0 abstract methods → 0% abstraction
-
It may contain only abstract methods → 100% abstraction
-
It may mix both → partial abstraction
Real-Life Example 2: College Admission
Every student must:
-
Submit documents
-
Pay fees
-
Attend orientation
But each department (CS, IT, Mechanical) manages process differently.
Abstract class:
abstract class AdmissionProcess {
abstract void documentCheck();
abstract void feePayment();
void orientation() {
System.out.println("Attend college orientation.");
}
}
class CS extends AdmissionProcess {
void documentCheck() {
System.out.println("CS Dept Document Check");
}
void feePayment() {
System.out.println("CS Dept Fee Payment");
}
}
class IT extends AdmissionProcess {
void documentCheck() {
System.out.println("IT Dept Document Check");
}
void feePayment() {
System.out.println("IT Dept Fee Payment");
}
}
When Should You Use Abstract Class?
Use abstract class when:
✔ You want partial abstraction
✔ Many classes share common behavior
✔ You need non-final variables
✔ You want to provide default methods
✔ You want to define constructors
Use Abstract Class when:
-
When classes share code (fields + methods)
-
"Is-a" relationship (Dog is an Animal)
Use Interface when:
-
Totally different classes need same behavior
-
Multiple inheritance needed
Practice Questions (Try These!)
-
Create an abstract class Phone with abstract method ring()
→ Make iPhone and Samsung extend it and implement their own ringtone. -
Create abstract class Employee with abstract method calculateSalary()
→ FullTimeEmployee and PartTimeEmployee extend it. -
Create abstract class Game with abstract method play()
→ Cricket, Football, Chess extend it.
Conclusion
-
Abstract class helps hide complexity
-
It provides a base structure for child classes
-
Supports both abstract + normal methods
-
Used for partial or full abstraction
-
Useful for large applications with a common blueprint
Keep practicing – you're doing amazing!
Happy Coding! ![]()
.png)