Introduction
Abstract class is a class that cannot be instantiated and may contain abstract methods (methods without body).
Syntax
abstract class ClassName {
// Abstract method (no body)
abstract returnType methodName();
// Concrete method (with body)
returnType method2() {
// Implementation
}
}
Basic Example
abstract class Animal {
// Abstract method
abstract void sound();
// Concrete method
void sleep() {
System.out.println("Sleeping...");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
// Animal a = new Animal(); // ✗ Error: Cannot instantiate
Animal dog = new Dog();
dog.sound(); // Bark
dog.sleep(); // Sleeping...
Animal cat = new Cat();
cat.sound(); // Meow
cat.sleep(); // Sleeping...
}
}
Rules for Abstract Classes
- Cannot instantiate abstract class
- Can have abstract and concrete methods
- Can have constructors
- Can have fields
- Can have static methods
- Abstract method must be in abstract class
- Subclass must implement all abstract methods
- If subclass doesn’t implement, it must also be abstract
Abstract Methods
abstract class Shape {
String color;
// Abstract methods (no implementation)
abstract double area();
abstract double perimeter();
// Concrete method
void displayColor() {
System.out.println("Color: " + color);
}
}
class Circle extends Shape {
double radius;
Circle(String color, double radius) {
this.color = color;
this.radius = radius;
}
@Override
double area() {
return Math.PI * radius * radius;
}
@Override
double perimeter() {
return 2 * Math.PI * radius;
}
}
class Rectangle extends Shape {
double length, width;
Rectangle(String color, double length, double width) {
this.color = color;
this.length = length;
this.width = width;
}
@Override
double area() {
return length * width;
}
@Override
double perimeter() {
return 2 * (length + width);
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new Circle("Red", 5);
System.out.println("Circle Area: " + circle.area());
circle.displayColor();
Shape rect = new Rectangle("Blue", 4, 6);
System.out.println("Rectangle Area: " + rect.area());
rect.displayColor();
}
}
Abstract Class with Constructor
abstract class Employee {
String name;
double salary;
// Constructor
Employee(String name, double salary) {
this.name = name;
this.salary = salary;
System.out.println("Employee constructor");
}
abstract void work();
void displayInfo() {
System.out.println("Name: " + name);
System.out.println("Salary: " + salary);
}
}
class Manager extends Employee {
String department;
Manager(String name, double salary, String department) {
super(name, salary); // Call abstract class constructor
this.department = department;
}
@Override
void work() {
System.out.println(name + " manages " + department);
}
}
public class Main {
public static void main(String[] args) {
Manager mgr = new Manager("John", 50000, "IT");
mgr.displayInfo();
mgr.work();
}
}
Partial Implementation
abstract class Vehicle {
String brand;
abstract void start();
abstract void stop();
// Common implementation
void displayBrand() {
System.out.println("Brand: " + brand);
}
}
abstract class FourWheeler extends Vehicle {
// Implement one method
@Override
void start() {
System.out.println("Four wheeler starting");
}
// stop() still abstract
}
class Car extends FourWheeler {
Car(String brand) {
this.brand = brand;
}
@Override
void stop() {
System.out.println("Car stopping");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car("Toyota");
car.start();
car.stop();
car.displayBrand();
}
}
Complete Example: Bank System
abstract class BankAccount {
protected String accountNumber;
protected String holderName;
protected double balance;
BankAccount(String accountNumber, String holderName) {
this.accountNumber = accountNumber;
this.holderName = holderName;
this.balance = 0;
}
// Abstract methods
abstract void deposit(double amount);
abstract boolean withdraw(double amount);
abstract double calculateInterest();
// Concrete methods
void displayBalance() {
System.out.println("Balance: " + balance);
}
void displayInfo() {
System.out.println("Account: " + accountNumber);
System.out.println("Holder: " + holderName);
displayBalance();
}
}
class SavingsAccount extends BankAccount {
private double interestRate = 4.5;
private double minimumBalance = 1000;
SavingsAccount(String accountNumber, String holderName) {
super(accountNumber, holderName);
}
@Override
void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount);
}
@Override
boolean withdraw(double amount) {
if (balance - amount >= minimumBalance) {
balance -= amount;
System.out.println("Withdrawn: " + amount);
return true;
}
System.out.println("Insufficient balance. Minimum required: " + minimumBalance);
return false;
}
@Override
double calculateInterest() {
return balance * interestRate / 100;
}
}
class CurrentAccount extends BankAccount {
private double overdraftLimit = 5000;
CurrentAccount(String accountNumber, String holderName) {
super(accountNumber, holderName);
}
@Override
void deposit(double amount) {
balance += amount;
System.out.println("Deposited: " + amount);
}
@Override
boolean withdraw(double amount) {
if (balance + overdraftLimit >= amount) {
balance -= amount;
System.out.println("Withdrawn: " + amount);
return true;
}
System.out.println("Overdraft limit exceeded");
return false;
}
@Override
double calculateInterest() {
return 0; // No interest on current account
}
}
public class Main {
public static void main(String[] args) {
SavingsAccount savings = new SavingsAccount("SA1001", "John");
savings.deposit(10000);
savings.withdraw(2000);
System.out.println("Interest: " + savings.calculateInterest());
savings.displayInfo();
System.out.println();
CurrentAccount current = new CurrentAccount("CA2001", "Alice");
current.deposit(5000);
current.withdraw(8000); // Uses overdraft
current.displayInfo();
}
}
Why Use Abstract Classes?
- Enforce contract: Subclasses must implement abstract methods
- Code reuse: Share common code in concrete methods
- Partial implementation: Provide some default behavior
- Template: Define structure for subclasses
- Polymorphism: Use abstract class reference
Abstract vs Concrete
// Abstract class
abstract class AbstractExample {
abstract void method1(); // No body
void method2() { // Has body
System.out.println("Concrete method");
}
}
// Concrete class
class ConcreteExample {
void method1() { // Must have body
System.out.println("Method 1");
}
void method2() {
System.out.println("Method 2");
}
}
Abstract Class with Static
abstract class MathOperations {
// Static method in abstract class
static int add(int a, int b) {
return a + b;
}
// Abstract method
abstract int multiply(int a, int b);
}
class Calculator extends MathOperations {
@Override
int multiply(int a, int b) {
return a * b;
}
}
public class Main {
public static void main(String[] args) {
// Call static method without object
System.out.println("Sum: " + MathOperations.add(10, 20));
Calculator calc = new Calculator();
System.out.println("Product: " + calc.multiply(10, 20));
}
}
Multiple Abstract Methods
abstract class Payment {
abstract void validatePayment();
abstract void processPayment();
abstract void sendReceipt();
// Template method
final void makePayment() {
validatePayment();
processPayment();
sendReceipt();
}
}
class CreditCardPayment extends Payment {
@Override
void validatePayment() {
System.out.println("Validating credit card");
}
@Override
void processPayment() {
System.out.println("Processing credit card payment");
}
@Override
void sendReceipt() {
System.out.println("Sending email receipt");
}
}
Comparison Table
| Feature | Abstract Class | Concrete Class |
|---|---|---|
| Instantiation | Cannot create objects | Can create objects |
| Abstract methods | Can have | Cannot have |
| Concrete methods | Can have | Must have all |
| Keyword | abstract | No keyword |
| Purpose | Partial implementation | Full implementation |
| Inheritance | Can be extended | Can be extended |
Abstract vs Interface
| Feature | Abstract Class | Interface |
|---|---|---|
| Methods | Abstract + Concrete | Abstract (Java 7), can have default (Java 8+) |
| Variables | Any type | public static final only |
| Constructor | Yes | No |
| Inheritance | Single | Multiple |
| Access modifiers | Any | public only (methods) |
| When to use | IS-A + shared code | CAN-DO capability |
Quick Reference
// Abstract class
abstract class Parent {
// Fields
int x;
// Constructor
Parent() { }
// Abstract method (no body)
abstract void method1();
// Concrete method (with body)
void method2() {
System.out.println("Concrete");
}
}
// Concrete subclass
class Child extends Parent {
@Override
void method1() { // Must implement
System.out.println("Implemented");
}
}
// Usage
// Parent p = new Parent(); // ✗ Error
Parent p = new Child(); // ✓ OK
Exam Tips
Remember:
- Cannot instantiate abstract class
- Use abstract keyword
- Can have abstract and concrete methods
- Abstract method has no body
- Subclass must implement all abstract methods
- Can have constructor
- Can have fields and static methods
- Used for partial implementation
- Enforces contract for subclasses
- Enables polymorphism
Common Questions:
- What is abstract class?
- Can we create object of abstract class?
- Abstract class vs interface?
- Can abstract class have constructor?
- What are abstract methods?
- Why use abstract classes?
- Can abstract class have concrete methods?
- Rules for abstract classes?