Java Abstract Class and Abstract Methods

In this tutorial, we will learn about Java abstract classes and abstract methods and we will also learn about the concept of abstraction in Java programming language.

Abstraction in Java

In Object oriented programming paradigm, abstraction is a process of hiding the implementation details from the user, only the needed information will be provided to the user without exposing internal implementation details. The user will have the information on what the object does but user will never know about how it does.

A real life example of abstraction is car steering. As a car driver, we know that when we turn the car steeting left, car will turn left side and when we turn car steering right, car will turn right side. However, we don't know the details of how car steering system works internally. By defining the abstract turning behaviour of car steering, car manufacture abstracted the internal complexities of steering system.

With abstraction in place, car manufacturer can implement different steering technology, without changing the expected behaviour of car steering system. As long as car turns right or left when driver turns steering right or left respectively, driver need not worry about internal steering technology of the car.

Abstract class and Abstract method in java are used for hiding certain details and showing only essential information to the user. In Java, keyword abstract is used to declare abstract class and abstract methods. abstract keyword is a non-access modifier applicable to classes and methods but not for Variables.


Abstract class in Java

An abstract class in Java is a class that cannot be instantiated on its own and may contain abstract methods. Abstract classes are meant to be subclassed, and they provide a common base for a group of related classes. An abstract class can have both abstract and non-abstract (concrete) methods. For example:

abstract class Shape {
    abstract void draw();
}
We cannot create objects of abstract classes in Java.

abstract class Shape {
    abstract void draw();
}

public class AbstractClass {
    public static void main(String[] args) {
        // Error: We cannot create an
        // object of abstract class
        Shape shape = new Shape();
    }
}
Output
Error: Shape is abstract; cannot be instantiated

In above program, we are trying to create an object of abstract class Shape. As we discussed earlier that we cannot instantiate an abstract class. Hence, it generated a compile time error.

Important points about abstract classes
  • An instance of an abstract class can not be created.

  • It can have abstract and non-abstract methods.

  • It can have constructors and static methods.

  • We can have an abstract class without any abstract method.

  • If a class contains at least one abstract method then it must be declare as abstract class.

  • Like inheritence, we can create subclasses from an abstract cass using extends keyword. A subclass object can access members of the abstract class.

Abstract method in Java

A method which is declared with abstract keyword and doesn't have its body is known as an abstract method. If you want a class to contain a method but you want the actual implementation of that method to be determined by child classes, you can declare the method in the parent class as an abstract.

Example of abstract method

abstract void draw();

Here, draw() is an abstract method. The body of draw() method is missing and is replaced by ;

  • The "abstract" keyword is used to declare the an abstract method. abstract keyword is used before the method name in the method declaration.

  • An abstract method contains a method signature, but no method body.

  • Instead of curly braces, an abstract method will have a semicolon (;) at the end.

  • The class containing an abstract method must be declared as abstract.

  • Any class inheriting the abstract class must implement abstract method or declare itself as abstract class.

Java program for abstract class and abstract method

// Abstract class
abstract class Shape {
    // Abstract method
    abstract void draw();
    // Non-Abstract method
    void printShapeType() {
        System.out.println("Geometric Shape");
    }
}

class Circle extends Shape {
    void draw() {
        System.out.println("Drawing a circle");
    }
}
public class Paint {
    public static void main(String[] args) {
        Circle cir = new Circle();
        cir.draw();
        cir.printShapeType();
    }
}
Output
Drawing a circle
Geometric Shape

In above program, we create an abstract class named "Shape" containing an abstract method "draw()" and a non-abstract method "printShapeType()". Class Circle is inheriting Shape class by providing implementation of abstract method draw(). Inside main method of Paint class, we can access abstract as well as non-abstract method of Shape class using an object of subclass Circle.

If the subclass Circle doesn't provide implementation of abstract method draw(), then Circle class must be declared as abstract.


Creating Abstract Classes and Methodsn

  • Declaring an Abstract Class : To declare an abstract class in Java, use the abstract keyword followed by the class keyword. Abstract classes can contain both abstract and non-abstract methods.
    abstract class Shape {
        // Abstract method declaration
        abstract void draw();
    
        // Concrete method
        void setColor(String color) {
            System.out.println("Setting color to: " + color);
        }
    }
    
    In this example, the Shape class is declared as abstract, and it contains an abstract method draw() and a concrete method setColor()

  • Implementing an Abstract Method : Any class that extends an abstract class with abstract methods must provide concrete implementations for those abstract methods. Failure to do so results in a compilation error.
    class Circle extends Shape {
        private double radius;
    
        Circle(double radius) {
            this.radius = radius;
        }
    
        @Override
        void draw() {
            System.out.println("Drawing circle with radius " 
              + radius);
        }
    }
    
    Here, the Circle class extends the Shape abstract class and provides a concrete implementation for the draw() method.

  • Abstract Classes with Constructors : Abstract classes can have constructors, and they are typically used to initialize the common state shared by subclasses. When a subclass is instantiated, the constructor of both the superclass and the subclass is called.
    abstract class Animal {
        private String name;
    
        Animal(String name) {
            this.name = name;
        }
    
        // Abstract method
        abstract void makeSound();
    
        String getName() {
            return name;
        }
    }
    
    In this example, the Animal abstract class has a constructor that initializes the name field. Subclasses extending Animal must provide an implementation for the abstract method makeSound().

Best Practices for Abstract Classes and Methods

  • Use Abstract Classes Judiciously : While abstract classes offer benefits, they should be used judiciously. Avoid unnecessary complexity and consider using interfaces or other design patterns when appropriate.

  • Choose Abstract Classes vs. Interfaces Thoughtfully : Consider the requirements of your design when choosing between abstract classes and interfaces. Abstract classes are suitable when you want to provide a common base with shared implementation, while interfaces are ideal for defining contracts for multiple classes.

  • Document Your Abstract Classes and Methods : Clearly document the purpose and expectations of your abstract classes and methods. Explain the contract that subclasses must adhere to and any specific behavior they should provide.

  • Follow Naming Conventions : Follow naming conventions to make your code more readable. Use meaningful names for abstract classes and methods to convey their purpose.

  • Avoid Deep Inheritance Hierarchies : Be cautious about creating deep inheritance hierarchies with multiple abstract classes. Deep hierarchies can lead to increased complexity and maintenance challenges.

Conclusion

Java abstract classes and abstract methods are powerful tools for achieving abstraction, code reuse, and designing well-structured class hierarchies. Whether you are designing a framework, modeling real-world entities, or implementing design patterns, understanding how to use abstract classes and methods is a fundamental skill for Java developers. By mastering these concepts and following best practices, you can create flexible, maintainable, and extensible code that meets the requirements of your software projects. Abstract classes provide a valuable mechanism for achieving both consistency and flexibility in your object-oriented designs.