Abstract Class in Java (OOP)

In Java, abstraction is implemented using abstract class and interface, which are two categories in Java with different rules and properties. An abstract class appears similar to any other class, but it is declared with the abstract keyword, and one can never instantiate an abstract class.

Why do we need abstract classes?

Abstract classes can never be instantiated. Consider this example: Suppose we are making a program that includes various animals, so we create various types of classes like Lion, Dog, Rabbit, etc. As a good programmer, we would first make a base class, Animal, which will contain common attributes of all animals like sound, color, etc. and common behaviour like run, eat, etc. All classes will extend this Animal class and override necessary methods. Something like this:

class Animal {
    public int noOfLegs;
    public String name;
    //constructor to initialise instance variables
    public Animal(){
        //some body
    }
    //methods
    public String run(){
        //some body
    }
    public String sound(){ 
        //some body
    }
}

class Lion extends Animal {
    //body of class including overriding methods of Animal
}

class Dog extends Animal {
    //body of class including overriding methods of Animal
}

Now we can instantiate animal classes by either using a reference variable of Animal type or their own. For eg, consider the following example:

Lion aLion = new Lion();
//a Lion object is a type of Lion

//or we can use Animal type reference which will make the program more poylmorphic (Think)
Animal aLion = new Lion();
//a Lion object is a type of Animal because it inherits Animal class

These instantiations make sense. But what if we instantiate Animal class:

Animal anAnimal = new Animal();

Does it make sense to instantiate Animal class? Think of the values of instance variables like noOfLegs? Think of the definition of methods like sound()? It doesn’t make sense to instantiate a class that was meant for extension only. This is where we need abstract classes because they can never be instantiated.

Abstract Methods

An abstract method is declared without any implementation and its declaration involves the abstract keyword, like this:

abstract void method();

Note: 

  • We don’t use curly braces at the end of an abstract method. 
  • If a class contains abstract methods, then it must be declared abstract. On the contrary, an abstract class may or may not have an abstract method.

Defining an Abstract class

The declaration of an abstract class contains an access modifier, the abstract keyword, name of the class, the implements clause (if present), and finally the extension clause (if present).

Syntax:

public abstract class NameClass {
    //body
}

The Body of an Abstract Class

The body of an abstract class can contain any type of method and variables that any other class can. It may or may not have abstract methods. It can contain static as well as final methods, constructors, and even the main() method too.

Writing the abstract Animal class

Here’s the abstract version of our Animal class:

abstract class Animal {
    public int noOfLegs;
    public String name;
    //constructor to initialise instance variables
    public Animal(int noOfLegs, String name) {
        this.noOfLegs = noOfLegs;
        this.name = name;
    }
    //abstract methods
    public abstract String run();
    public abstract String sound();
}

Extending the Abstract class

Now we have the skeletal form of an animal. Let's try to use this form to create an animal that actually exists, like a Lion or a Dog. We will create concrete classes that extend the abstract class by using extends clause and then give proper implementation to the abstract methods.

Syntax:

class Lion extends Animal {
    //body of Lion class
}

class Dog extends Animal {
    //body of Dog class
}

Overriding methods in concrete class

This section requires knowledge of method overriding.

A class that extends an abstract class and does not override all of its abstract methods is also an abstract class. Therefore, in order to use Lion and Dog as concrete classes, we must override all abstract methods of the Animal class. Note: We can even override non-abstract, non-static, non-final methods of the abstract class too.

Our concrete classes will look like this:

class Lion extends Animal {
    //variables and methods of Lion class itself
    public Lion (int noOfLegs, String name){
        super(noOfLegs, name);
    }
    @Override
    public String run(){
        return "Running slowly";
    }
    @Override
    public String sound(){
        return "Roars";
    }
}

class Dog extends Animal {
    //variables and methods of Dog class itself        
        
    public Dog (int noOfLegs, String name){
        super(noOfLegs, name);
    }
    @Override
    public String run(){
        return "Running fastly";
    }
    @Override
    public String sound(){
        return "Barks";
    }
}

Note: We are calling parent class constructor from the base class constructor by using the super keyword. This involve the idea of constructor chaining.

We’ve successfully implemented the idea of abstract classes. Try running the following lines of code:

Animal aLion = new Lion (4,"LION");
System.out.println("Printing details of Lion:\n");
System.out.println(aLion.run());
System.out.println(aLion.sound());

Animal anAnimal = new Animal (0,"NONE");

The last line of above code will generate an error because we are trying to instantiate an abstract class.

Key Features of Abstract class

  • It can not be instantiated.
  • It may or may have abstract methods and it can have constructors.
  • It can have final and static methods but neither of them can not be declared abstract methods.
  • If a class contains abstract methods, then it must be declared abstract.
  • An abstract class can be extended by another abstract class. This implies, that the child's abstract class does not need to implement all the abstract methods (although it can).

Examples of Abstract Classes in JDK

  1. AbstractMap : Provides a skeletal implementation of Map interface.
  2. AbstractSet : Provides a skeletal implementation of the Set interface. 
  3. AbstractCollection : Provides a skeletal implementation of Collection interface.

Enjoy learning, Enjoy OOPS!

Share on social media:

More blogs to explore

Our weekly newsletter

Subscribe to get weekly content on data structure and algorithms, machine learning, system design and oops.

© 2022 Code Algorithms Pvt. Ltd.

All rights reserved.