Imagine you are designing software for a company that manages different types of vehicles. Every vehicle has some common behavior, such as starting and stopping, but the exact way a car, bike, or truck performs certain operations can be different. You want to define the common structure once without forcing every detail into the parent class. This is where an abstract class becomes useful.
An abstract class is a class that is designed to act as a base class for other classes. It can contain common fields, constructors, concrete methods, and abstract methods. Unlike a normal class, an abstract class cannot be instantiated directly.
An abstract class is best understood as a partially implemented class. It provides the common functionality that subclasses can reuse while leaving some behavior for subclasses to define.
Why Do We Need Abstract Classes?
In real applications, several classes often share common properties and behavior but are not identical. For example, Car, Bike, and Truck are all vehicles. They may share a brand, speed, and start operation, but their specific driving behavior can differ.
Without abstraction, developers may either duplicate common code or create a parent class containing behavior that does not make sense for every child class. An abstract class provides a clean middle ground: share what is common and force subclasses to provide what is specific.
Real-World Analogy
Think about a blueprint for a house. The blueprint can define common structural rules such as having doors, windows, rooms, and electrical connections. However, the exact interior design may be different for every house.
An abstract class works in a similar way. It defines the common foundation, while concrete subclasses complete the implementation according to their own requirements.
What Makes a Class Abstract?
A class is declared abstract by using the abstract keyword before the class declaration.
abstract class Vehicle
{
// Common members and behavior
}
Because Vehicle is abstract, Java does not allow us to create an object of it directly.
Vehicle v = new Vehicle(); // Compile-time error
You can declare a reference variable whose type is an abstract class, but you cannot directly create an object of that abstract class.
Abstract Class with Concrete Methods
An abstract class does not have to contain only abstract methods. It can contain completely implemented methods as well.
abstract class Vehicle
{
void start()
{
System.out.println("Vehicle is starting");
}
}
A subclass can inherit and use the start() method without rewriting it.
class Car extends Vehicle
{
}
class Main
{
public static void main(String[] args)
{
Car car = new Car();
car.start();
}
}
Here, Vehicle provides reusable behavior, while Car inherits that behavior automatically.
Abstract Class with Fields
An abstract class can contain instance variables just like a normal class.
abstract class Employee
{
String name;
double salary;
void displayEmployee()
{
System.out.println(name);
System.out.println(salary);
}
}
The subclass can use these inherited fields and methods.
class Developer extends Employee
{
}
class Main
{
public static void main(String[] args)
{
Developer developer = new Developer();
developer.name = "Bibhu";
developer.salary = 75000;
developer.displayEmployee();
}
}
This is one of the major practical benefits of abstraction: common state and common behavior can be placed in one reusable parent class.
Abstract Class with Constructors
An abstract class can have constructors. This sometimes surprises beginners because they cannot create an object of the abstract class directly. The constructor is still useful because it executes when a subclass object is created.
abstract class Employee
{
String name;
Employee(String name)
{
this.name = name;
}
void displayName()
{
System.out.println(name);
}
}
class Developer extends Employee
{
Developer(String name)
{
super(name);
}
}
class Main
{
public static void main(String[] args)
{
Developer developer = new Developer("Bibhu");
developer.displayName();
}
}
When the Developer object is created, its constructor calls super(name), which invokes the constructor of the abstract parent class.
An abstract class cannot be instantiated directly, but its constructor can still execute as part of subclass object creation.
Abstract Class Does Not Always Need an Abstract Method
A common misconception is that every abstract class must contain at least one abstract method. That is not required.
abstract class Database
{
void connect()
{
System.out.println("Connecting to database");
}
}
This class is abstract even though it contains no abstract method. The developer may intentionally prevent direct instantiation while still providing reusable functionality to subclasses.
Abstract Class Can Contain Different Types of Members
An abstract class can contain a combination of members, including fields, constructors, concrete methods, abstract methods, static members, and other supported class members.
abstract class Payment
{
String transactionId;
Payment(String transactionId)
{
this.transactionId = transactionId;
}
void printTransactionId()
{
System.out.println(transactionId);
}
abstract void processPayment();
}
This design is powerful because the parent class can provide the common transaction information and functionality while subclasses decide how payment processing actually works.
Abstract Class and Object Creation
You cannot directly create an object of an abstract class.
abstract class Animal
{
}
class Main
{
public static void main(String[] args)
{
Animal animal = new Animal(); // Compile-time error
}
}
However, you can create an object of a concrete subclass and store it in an abstract class reference.
abstract class Animal
{
void eat()
{
System.out.println("Animal is eating");
}
}
class Dog extends Animal
{
}
class Main
{
public static void main(String[] args)
{
Animal animal = new Dog();
animal.eat();
}
}
The reference type is Animal, but the actual object is a Dog. This pattern becomes especially important when abstraction and polymorphism are used together.
Abstract Class and Inheritance
An abstract class is normally used as a parent class. A concrete subclass extends it and inherits its implemented members.
abstract class Shape
{
void display()
{
System.out.println("This is a shape");
}
}
class Circle extends Shape
{
}
class Rectangle extends Shape
{
}
class Main
{
public static void main(String[] args)
{
Circle circle = new Circle();
Rectangle rectangle = new Rectangle();
circle.display();
rectangle.display();
}
}
Both subclasses reuse the same implementation from Shape. If the common behavior changes, it can be updated in one place rather than duplicated across every subclass.
Abstract Class vs Normal Class
A normal class can be instantiated directly, whereas an abstract class cannot. The important point is that abstraction is not simply about preventing object creation; it is about designing a meaningful inheritance hierarchy.
| Feature | Normal Class | Abstract Class |
|---|---|---|
| Object creation | Allowed | Not allowed directly |
| Concrete methods | Allowed | Allowed |
| Abstract methods | Not allowed | Allowed |
| Fields | Allowed | Allowed |
| Constructors | Allowed | Allowed |
| Inheritance | Can be extended | Designed primarily as a base class |
Common Beginner Mistakes
- Trying to create an object directly from an abstract class.
- Assuming an abstract class must contain an abstract method.
- Assuming an abstract class cannot have constructors.
- Thinking every method inside an abstract class must be abstract.
- Using an abstract class when there is no meaningful parent-child relationship.
- Forgetting that an abstract class can be used as a reference type for polymorphism.
Best Practices
- Use an abstract class when multiple related classes share meaningful state or implementation.
- Keep genuinely common behavior in the abstract parent instead of duplicating it in subclasses.
- Use abstract methods when the parent knows that a behavior must exist but cannot provide a suitable implementation.
- Avoid creating an abstract class merely because the class name sounds generic.
- Keep the abstraction focused on the common contract and responsibilities of its subclasses.
Interview Insights
Question: Can we create an object of an abstract class?
Answer: No. An abstract class cannot be instantiated directly. However, a reference of the abstract class type can refer to an object of a concrete subclass.
Question: Can an abstract class have a constructor?
Answer: Yes. Its constructor executes when a subclass object is created, usually through an implicit or explicit super() call.
Question: Can an abstract class contain normal methods?
Answer: Yes. An abstract class can contain fully implemented concrete methods along with abstract methods.
Question: Can an abstract class exist without an abstract method?
Answer: Yes. The abstract keyword on the class itself is sufficient to prevent direct instantiation.
Quick Revision
| Concept | Key Point |
|---|---|
| Abstract class | A class that cannot be instantiated directly and is commonly used as a base class. |
| abstract keyword | Used to declare an abstract class or abstract method. |
| Concrete method | A method that contains an implementation and can be inherited by subclasses. |
| Abstract method | A method declared without an implementation that subclasses are responsible for implementing. |
| Constructor | Allowed in an abstract class and executed during subclass object creation. |
| Reference | An abstract class reference can point to an object of a concrete subclass. |
Final Takeaway
An abstract class gives you a powerful way to model a family of related classes without forcing the parent class to provide every implementation. It lets you place shared state and reusable behavior in one location while allowing subclasses to specialize what makes them different. Once you understand this idea, abstract classes become much more than a syntax rule—they become a practical tool for designing maintainable object-oriented systems.
