Abstract Class in Java (OOP)

What is an Abstract Class in Java?

The word “abstract” means something that defines the skeletal details of an object. In programming, abstraction is a principle in which a programmer hides those components of an object which are irrelevant to other objects in order to reduce complexity and increase the efficiency of the program.

In Java language, abstraction is implemented with abstract class and interface. Abstract class and interface are two different types of classes in Java with different rules and properties.

An abstract class looks 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 have a very unique property which is, that they can never be instantiated. Having said that consider this example:

Imagine we are making a program that consists of various animals, so we make various types of classes like Lion, Dog, Rabbit, etc. As a smart developer, we would first make a base class say Animal which will contain basic properties of all animals like sound, etc. All the 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 the animals by either using a reference variable of Animal type or their own. For eg, consider the following lines:

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 meth();

Note: 

  • We don’t even 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, the name of the class, the implements clause (if present), and finally the extension clause (if present).

Syntax:

public abstract class NameClass {
    //body
}

The body

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 that 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 the 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 the 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: The boldface lines involve constructor chaining, where we call the parent class constructor from the base class’ constructor by using the super keyword.

That’s it! 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 boldface line will generate an error because we are trying to instantiate an abstract class, which is what we wanted!

Key features of Abstract class

  1. It can not be instantiated.
  2. It may or may have abstract methods and it can have constructors.
  3. It can have final and static methods but neither of them can not be declared abstract methods.
  4. If a class contains abstract methods, then it must be declared abstract.
  5. 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 the Map interface.
  2. AbstractSet — provides a skeletal implementation of the Set interface. 
  3. AbstractCollection — provides a skeletal implementation of the Collection interface and it is the mother class of the previous two examples and many other classes.

Enjoy learning, Enjoy OOPS!

More From EnjoyAlgorithms

Our weekly newsletter

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

Follow Us:

LinkedinMedium

© 2020 EnjoyAlgorithms Inc.

All rights reserved.