Java Abstract Class
Abstract class is a special class which is defined using abstract keyword, and we can not create the object of the abstract class directly.
We can declare all the members like constructors, instance variables, static variables, static methods, final methods, and concrete methods inside an abstract class, just as we can inside a concrete class. And abstract class can contain only abstract methods or a combination of abstract and concrete methods.
So here abstract method is a method that is declared without an implementation (without a body). It only has the method signature and ends with a semicolon.
If an abstarct clsss have an abstract method then the class must be declared as abstract. But if a class is declared as abstract, it may or may not have an abstract method.
When a class is inherited from an abstract class, it must provide implementations for all the inherited abstract methods. If it does not, then the subclass must also be declared as abstract.
We can can not make the abstract class as final because abstract class is meant to be inherited and final class can not be inherited. So, both keywords are contradictory to each other.
Following modifiers are not allowed with an abstract class: final, synchronized, and static (for top-level classes).
| Feature | Abstract class | Concrete class |
|---|---|---|
| Can be instantiated directly | No | Yes |
| Can declare abstract methods | Yes | No |
| Can contain implemented methods | Yes | Yes |
| Typical role | Define shared behavior or a contract for subclasses | Provide a complete implementation |
Syntax of Abstract Class in Java
abstract class ClassName {
// variables
// concrete method
returnType concreteMethodName() {
// implementation
}
// abstract method
abstract returnType abstractMethodName();
}Example
abstract class Animal {
abstract void makeSound();
void eat() {
System.out.println("Eating...");
}
}Why Use Abstract Class in Java?
It is mainly used to define the common structure and behavior, or specification (blueprint), through concrete methods and to enforce subclasses to implement certain methods through abstract methods.
We use an abstract class to define some common methods that subclasses can extend and modify according to their needs.
Real-time library example: InputStream and BufferedInputStream
InputStream is an abstract class in Java's java.io library that provides common methods for reading data. Its subclasses, such as FileInputStream and BufferedInputStream, provide different ways to read data.
InputStreamprovides common methods likeread()andclose().FileInputStreamextendsInputStreamto read data directly from a file.BufferedInputStreamextendsInputStreamto read data efficiently using a buffer.
Example-1:
abstract class Vehicle {
// Abstract method
abstract void start();
// Concrete method
void stop() {
System.out.println("Vehicle stopped");
}
}Here:
abstract class Vehiclemeans Vehicle is an abstract class.
And:
abstract void start();is an abstract method.
It only defines what should be done, not how it should be done.
Now Lets learn from simple examples.
1. Abstract Classes Can Contain Concrete and Abstract Methods
It can contain concrete methods (method having body or implementation) as well as abstract methods( method having no body or implementation).
Example
abstract class Vehicle {
// Concrete method
void start() {
System.out.println("Vehicle is starting");
}
// Abstract method
abstract void move();
}
class Car extends Vehicle {
// Providing implementation for the abstract method
@Override
void move() {
System.out.println("Car is moving");
}
}Here, start() is a concrete method because it has an implementation, while move() is an abstract method because it only declares the method without providing an implementation.
OR -
abstract class Vehicle {
// Abstract method
abstract void start();
// Concrete method
void stop() {
System.out.println("Vehicle stopped");
}
}
class Car extends Vehicle {
@Override
void start() {
System.out.println("Car starts with a key");
}
}
class Bike extends Vehicle {
@Override
void start() {
System.out.println("Bike starts with a button");
}
}
public class HelloWorld {
public static void main(String[] args) {
Vehicle car = new Car();
car.start();
car.stop();
Vehicle bike = new Bike();
bike.start();
bike.stop();
}
}2. Members Allowed Inside an Abstract Class
We can declare all the members inside abstract class like constructors, instance variables, static methods, final methods, concrete methods, and abstract methods.
Example
abstract class Vehicle {
// Instance variable
String brand = "Toyota";
// Constructor
Vehicle() {
System.out.println("Vehicle constructor");
}
// Static method
static void info() {
System.out.println("This is a vehicle");
}
// Final method
final void fuelType() {
System.out.println("Uses fuel");
}
// Concrete method
void start() {
System.out.println("Vehicle started");
}
// Abstract method
abstract void move();
}3. Abstract Classes Can Implement Interfaces
Like concrete class Abstract classes also can implement interfaces.
Example
interface Animal {
void makeSound();
}
abstract class Dog implements Animal {
// Common implementation
void eat() {
System.out.println("Dog is eating");
}
// makeSound() can remain abstract
}
class Puppy extends Dog {
@Override
public void makeSound() {
System.out.println("Puppy is barking");
}
}Here, Dog implements the Animal interface but does not implement makeSound(). Since Dog is abstract, this is allowed. The concrete class Puppy provides the implementation.
4. Creating an Object Through a Concrete Subclass
We cannot create an object directly from an abstract class, but we can create an object of its concrete subclass and refer to it using the abstract class type.
Example
abstract class Animal {
abstract void makeSound();
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog is barking");
}
}
public class HelloWorld {
public static void main(String[] args) {
Animal animal = new Dog();
animal.eat();
animal.makeSound();
}
}Here:
Animal animal = new Dog();- Animal → abstract class/reference type
- Dog → concrete subclass
- new Dog() → creates the actual object
- animal → refers to the Dog object
So, the object is created from the subclass, not from the abstract class.
5. An Abstract Class Can Contain Final Methods
An abstract class can contain final methods. A final method provides a complete implementation and cannot be overridden by its subclasses.
Example
abstract class Vehicle {
final void start() {
System.out.println("Vehicle is starting");
}
abstract void move();
}
class Car extends Vehicle {
@Override
void move() {
System.out.println("Car is moving");
}
// Cannot override the final method
// void start() { } // ❌ Compile-time error
}Here, start() is a final method, so the Car class can use it but cannot override its implementation.
6. Abstract Inner Classes Are Allowed
An abstract class can be declared inside another class. When it is a non-static member class, as in this example, it is called an abstract inner class. It can contain abstract and concrete methods, just like a regular abstract class.
Example
class Outer {
abstract class Inner {
abstract void display();
void show() {
System.out.println("Concrete method");
}
}
}
class HelloWorld extends Outer {
class Child extends Inner {
@Override
void display() {
System.out.println("Abstract method implemented");
}
}
public static void main(String[] args) {
HelloWorld main = new HelloWorld();
Child child = main.new Child();
child.display();
child.show();
}
}Here, Inner is an abstract inner class declared inside Outer. The Child class extends Inner and provides the implementation of its abstract method.
7. A Class Containing an Abstract Method Must Be Abstract
If a class contains at least one abstract method, the class itself must be declared using the abstract keyword. This is because an abstract method does not have an implementation, so the class cannot provide a complete implementation for all its methods.
Example
abstract class Animal {
// Abstract method
abstract void makeSound();
}Here, makeSound() is an abstract method, so Animal must also be declared as an abstract class.
❌ Invalid:
class Animal {
abstract void makeSound();
}This will result in a compile-time error because Animal is not declared as an abstract class.
8. A Subclass Must Be Abstract If It Does Not Implement All Inherited Abstract Methods
If a subclass inherits one or more abstract methods from its parent class but does not provide implementations for all of them, the subclass must also be declared as an abstract class.
Example
abstract class Animal {
abstract void eat();
abstract void makeSound();
}
abstract class Dog extends Animal {
@Override
void eat() {
System.out.println("Dog is eating");
}
// makeSound() is not implemented
}Here, Dog implements eat() but does not implement makeSound(). Therefore, Dog must also be declared as abstract.
A concrete subclass must have implementations for all inherited abstract methods. It can provide them itself or inherit suitable implementations from its parent class.
9. An Abstract Class Cannot Be Final
An abstract class cannot be declared as final because both keywords have conflicting purposes.
- abstract means the class is designed to be extended by another class.
- final means the class cannot be extended.
Therefore, Java does not allow a class to be both abstract and final.
abstract final class Animal { // ❌ Compile-time error
}Instead, an abstract class should be extended by a subclass:
abstract class Animal {
abstract void makeSound();
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog is barking");
}
}Here, Animal is abstract and can be extended by Dog.
10. Certain Modifiers Cannot Be Used With an Abstract Class
Some modifiers are not valid or are incompatible with an abstract class, depending on where the class is declared.
An abstract class cannot be final, and synchronized is not allowed on a class declaration. A top-level class cannot be static, but a static nested class can be abstract.
- final — A final class cannot be extended, whereas an abstract class is designed to be extended.
- static — A top-level class cannot be declared static. A nested class can be static, but it can still be abstract.
- synchronized — synchronized is not a valid modifier for a class declaration.
- private — A top-level class cannot be private. However, a nested abstract class can be declared private.
abstract final class Animal { } // ❌ Cannot be both abstract and final
abstract synchronized class Test { } // ❌ InvalidA nested abstract class can, however, be declared private or static:
class Outer {
private abstract class Inner {
abstract void display();
}
static abstract class Nested {
abstract void show();
}
}11. Static Members of an Abstract Class Can Be Accessed Using the Class Name
An abstract class can contain static variables and static methods. Since static members belong to the class rather than to an object, they can be accessed directly using the abstract class name.
Example
abstract class Animal {
static String type = "Animal";
static void display() {
System.out.println("This is an animal");
}
}
public class HelloWorld {
public static void main(String[] args) {
System.out.println(Animal.type);
Animal.display();
}
}Output
Animal
This is an animalHere, we access type and display() using Animal, even though Animal is an abstract class.
Important: We cannot do this:
Animal animal = new Animal(); // ❌ Cannot create objectBut static members can be accessed without creating an object.
12. Instance Members Can Be Accessed Using a Subclass Object
An abstract class can contain instance variables and instance methods. These members can be accessed through an object of a concrete subclass that extends the abstract class.
Example
abstract class Animal {
String name = "Dog";
void eat() {
System.out.println("Animal is eating");
}
abstract void makeSound();
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Dog is barking");
}
}
public class HelloWorld {
public static void main(String[] args) {
Dog dog = new Dog();
System.out.println(dog.name);
dog.eat();
}
}Here, name and eat() are instance members of the abstract class Animal. They are accessed using the Dog object.
Dog dog = new Dog();
System.out.println(dog.name);
dog.eat();Note: The object is created from the concrete subclass (Dog), not from the abstract class (Animal).
13. An Abstract Class's Instance Block and Constructor Run When a Subclass Object Is Created
An abstract class can have an instance initialization block and a constructor. When we create an object of a concrete subclass, the abstract parent class's instance block and constructor also run as part of initializing that object.
Example
abstract class Animal {
// Instance initialization block
{
System.out.println("Animal instance block");
}
Animal() {
System.out.println("Animal constructor");
}
}
class Dog extends Animal {
{
System.out.println("Dog instance block");
}
Dog() {
super();
System.out.println("Dog constructor");
}
}
public class HelloWorld {
public static void main(String[] args) {
Dog dog = new Dog();
}
}Output
Animal instance block
Animal constructor
Dog instance block
Dog constructorHere, new Dog() calls the Dog constructor, which calls the Animal constructor through super(). After Animal's superclass constructor returns, the Animal instance block runs before the Animal constructor body. Then the Dog instance block runs before the remaining Dog constructor body.
If we omit super() in this example, Java inserts it automatically. Only one Dog object is created; the parent constructor initializes the inherited part of that same object.
See you in next page....🙂