The abstract keyword in Java is an important concept for building flexible and reusable code. It allows developers to create classes and methods that define a structure but leave some details for subclasses to implement. This approach helps in designing a blueprint for future development while enforcing certain rules.
In Java, abstract classes and methods provide a way to set up a general outline for different types of objects. They encourage organised coding by focusing on common features.
In this blog, we will see different rules which are used for the abstract keyword and how the abstract classes and abstract methods work. We will also cover practical examples, their advantages and best practices.
Abstract Classes in Java
An abstract class in Java is a class that cannot be instantiated directly. It serves as a blueprint for other classes, providing a base structure but leaving some methods without an implementation. Abstract classes are meant to be extended by other classes that provide concrete implementations for the abstract methods. They help in designing a flexible hierarchy while sharing common functionality.
Why Can’t We Create an Object of an Abstract Class?
Abstract classes are incomplete: They may contain methods without an implementation, which means the class is not fully defined. An instance of an incomplete class would not be meaningful.
Designed for extension: Abstract classes are intended to be extended by other subclasses, which complete the implementation of abstract methods.
Enforces a template: Using abstract classes ensures that subclasses follow a certain structure without allowing direct instantiation.
How to Create an Abstract Class?
To create an abstract class in Java, use the abstract keyword before the declaration of the class. An abstract class may have a mix of abstract methods (with a body) and concrete methods (with a body). Here’s the syntax and explanation:
// Syntax for an abstract class
abstract class Animal {
// Abstract method (no body)
abstract void makeSound();
// Non-abstract method
void sleep() {
System.out.println("Sleeping...");
}
}
Explanation:
abstract class Animal: This declares Animal as an abstract class, meaning it cannot be instantiated directly.
abstract void makeSound(): This is an abstract method. Any subclass of Animal must implement this method.
void sleep(): This is a regular method with a body and can be used as is by subclasses.
Using an abstract class helps define common behaviour while leaving some methods for subclasses to complete, allowing for a consistent structure across related classes.
Get curriculum highlights, career paths, industry insights and accelerate your technology journey.
Download brochure
Abstract Methods in Java
An abstract method is defined as a method without implementation. In Java, abstract methods are used in the abstract class to declare a method signature, which is to be implemented through the subclasses. This guarantees that every subclass is implemented according to a general design principle, which offers every subclass the freedom to implement the method behaviour in a designated way.
To declare an abstract method, write the word abstract before the method signature and don’t write the method body.
Syntax for Abstract Method
// Syntax for an abstract method
abstract void methodName();
Explanation:
abstract: The keyword used to declare an abstract method.
void methodName(): The method signature. It includes the return type (void in this case) and the method name (methodName). There is no method body, as the implementation will be provided by the subclass.
Code Example with Comments
Here’s an example that demonstrates how to use abstract methods in Java:
// Abstract class with an abstract method
abstract class Animal {
// Abstract method (no implementation)
abstract void makeSound();
// Regular method
void eat() {
System.out.println("Eating...");
}
}
// Subclass that provides implementation for the abstract method
class Dog extends Animal {
// Implementing the abstract method
void makeSound() {
System.out.println("Woof! Woof!");
}
}
// Main class to run the program
public class Main {
public static void main(String[] args) {
// Create an object of the Dog class
Dog dog = new Dog();
// Call the implemented method
dog.makeSound();
// Call the inherited method
dog.eat();
}
}
Output
Woof! Woof!
Eating...
Explanation
Animal is an abstract class with an abstract method makeSound() and a regular method eat().
Dog is a subclass of Animal that provides an implementation for the makeSound() method.
In the Main class, a Dog object is created. The makeSound() method (which is implemented in the Dog class) is called, displaying “Woof! Woof!”.
The eat() method, which is a regular method from the Animal class, is also called, showing “Eating…”.
Use abstract with classes that are supposed to be extended: Mark a class as the abstract class if it’s not intended to be instantiated directly. However, it can be used as a base class for other subclasses.
Extend abstract classes to provide specific implementations: When a subclass extends an abstract class, it ought to provide implementations for all abstract methods unless it’s also declared abstract.
Combine abstract with inheritance: Use abstract classes to share code among related classes while enforcing a common interface.
Declare methods as abstract if they lack a body: The abstract keyword should be employed for methods that have no implementation at all; these methods need to be implemented at the subclass level.
Define all the non-abstract methods in an abstract class if needed: There may be a few abstract methods and there may be some methods with implementations of it in a single class.
Don’ts
Do not create an instance of an abstract class: An object of an abstract class cannot be created directly.
Do not specify a method as abstract in a class that is not abstract: A non-abstract class can’t have abstract methods.
Non-abstract class must not contain an abstract method: An abstract method is an exclusive member of an abstract class.
An abstract method must not have a method body: Don’t implement the Abstract method and declare it without the body. However, you can implement it in the derived class.
Examples of Abstract Keyword
Here, we have covered a few examples showcasing the different properties of the abstract keyword.
Example 1: Abstract Class with Multiple Abstract Methods
This example demonstrates an abstract class with more than one abstract method.
In this example, the Animal class has two abstract methods (makeSound() and move()) and one regular method (sleep()). The Cat class provides implementations for both abstract methods.
// Abstract class with two abstract methods
abstract class Animal {
abstract void makeSound();
abstract void move();
// Non-abstract method
void sleep() {
System.out.println("Sleeping...");
}
}
// Subclass implementing both abstract methods
class Cat extends Animal {
void makeSound() {
System.out.println("Meow!");
}
void move() {
System.out.println("Cat is running.");
}
}
// Main class to execute the program
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.makeSound();
cat.move();
cat.sleep();
}
}
Output
Meow!
Cat is running.
Sleeping...
Example 2: Extending an Abstract Class without Implementing All Methods
This example shows that if a subclass does not implement all abstract methods, it must also be declared as abstract.
In the code below, the WashingMachine class extends Appliance but only provides an implementation for turnOn(). Since it does not implement turnOff(), it is declared as abstract. The SmartWashingMachine class extends WashingMachine and provides the implementation for turnOff().
// Abstract class with an abstract method
abstract class Appliance {
abstract void turnOn();
abstract void turnOff();
}
// Subclass without implementing all abstract methods
abstract class WashingMachine extends Appliance {
// Only implements one method
void turnOn() {
System.out.println("Washing machine turned on.");
}
}
// Subclass providing the remaining implementation
class SmartWashingMachine extends WashingMachine {
void turnOff() {
System.out.println("Washing machine turned off.");
}
}
// Main class to run the program
public class Main {
public static void main(String[] args) {
SmartWashingMachine machine = new SmartWashingMachine();
machine.turnOn();
machine.turnOff();
}
}
Output
Washing machine turned on.
Washing machine turned off.
Example 3: Using Abstract Classes with Constructors
This example shows that abstract classes can have constructors, which can be used to initialise fields.
In this example, the Computer class is an abstract class with a constructor to initialise the brand field. The Laptop class extends the Computer and provides an implementation for the displaySpecs() method. The constructor in Laptop uses super to call the parent class’s constructor.
// Abstract class with a constructor
abstract class Computer {
String brand;
// Constructor
Computer(String brand) {
this.brand = brand;
}
// Abstract method
abstract void displaySpecs();
// Concrete method
void showBrand() {
System.out.println("Brand: " + brand);
}
}
// Subclass providing implementation for the abstract method
class Laptop extends Computer {
int ram;
Laptop(String brand, int ram) {
super(brand);
this.ram = ram;
}
void displaySpecs() {
System.out.println("Laptop Specs - Brand: " + brand + ", RAM: " + ram + "GB");
}
}
// Main class to run the program
public class Main {
public static void main(String[] args) {
Laptop laptop = new Laptop("Dell", 16);
laptop.showBrand();
laptop.displaySpecs();
}
}
Output
Brand: Dell
Laptop Specs - Brand: Dell, RAM: 16GB
Example 4: Abstract Class Implementing an Interface
This example demonstrates that an abstract class can implement an interface, but it doesn’t have to implement all interface methods. The remaining methods can be left for a concrete subclass to implement.
In the code below, the Shape class implements the Drawable interface but does not provide an implementation for the draw() method, leaving it to the Rectangle subclass to implement.
// Interface with a method declaration
interface Drawable {
void draw();
}
// Abstract class implementing the interface
abstract class Shape implements Drawable {
String color;
Shape(String color) {
this.color = color;
}
// Non-abstract method
void showColor() {
System.out.println("Color: " + color);
}
}
// Subclass providing implementation for the interface method
class Rectangle extends Shape {
int width, height;
Rectangle(String color, int width, int height) {
super(color);
this.width = width;
this.height = height;
}
// Implementing the interface method
public void draw() {
System.out.println("Drawing a rectangle with width " + width + " and height " + height);
}
}
// Main class to run the program
public class Main {
public static void main(String[] args) {
Rectangle rectangle = new Rectangle("Red", 4, 5);
rectangle.showColor();
rectangle.draw();
}
}
Output
Color: Red
Drawing a rectangle with width 4 and height 5
Example 5: Abstract Class with Final Variables
This example demonstrates that abstract classes can have final variables, which are constants and cannot be changed once initialised.
In the code below, the Vehicle abstract class has a final variable maxSpeed that is initialised through the constructor. The Bike class extends Vehicle and provides an implementation for the displayInfo() method. The final variable ensures that the maxSpeed cannot be changed after it’s assigned.
// Abstract class with a final variable
abstract class Vehicle {
final int maxSpeed;
Vehicle(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
// Abstract method
abstract void displayInfo();
// Concrete method to show max speed
void showMaxSpeed() {
System.out.println("Max Speed: " + maxSpeed + " km/h");
}
}
// Subclass implementing the abstract method
class Bike extends Vehicle {
String model;
Bike(int maxSpeed, String model) {
super(maxSpeed);
this.model = model;
}
// Implementing the abstract method
void displayInfo() {
System.out.println("Bike Model: " + model);
}
}
// Main class to run the program
public class Main {
public static void main(String[] args) {
Bike bike = new Bike(180, "Yamaha");
bike.displayInfo();
bike.showMaxSpeed();
}
}
Output
Bike Model: Yamaha
Max Speed: 180 km/h
Abstract and Final Classes
In Java, it is very important to understand the specific use of the two keywords abstract and final, when we implement classes and methods. An abstract class and method are created with the intention that these classes will be extended or their methods will be overridden. On the other hand, the final keyword is used to restrict the overwrite.
Difference Between Abstract and Final Classes
Here’s a table that outlines the main differences between abstract and final classes:
Feature
Abstract Class
Final Class
Purpose
Designed to be extended by other classes.
Prevents the class from being extended or subclassed.
Instantiation
Cannot be instantiated directly.
Can be instantiated, like any other concrete class.
Method Behavior
Can have both abstract (unimplemented) and concrete methods.
Cannot have abstract methods, all methods must be defined.
Inheritance
Can be inherited by other classes.
Cannot be inherited by other classes.
Keyword Usage with Methods
Allows methods to be declared abstract (must be overridden).
final methods cannot be overridden by subclasses.
Combination with Other Keywords
Cannot be used with final (abstract and final are mutually exclusive).
Can be used with static and other modifiers.
Example of Final Class
The Calculator class is marked as final, meaning it cannot be extended by any other class. This ensures that the class’s behaviour remains unchanged.
// Final class example
final class Calculator {
// Method to add two numbers
int add(int a, int b) {
return a + b;
}
}
// Attempt to extend the final class (this will cause a compilation error)
// class AdvancedCalculator extends Calculator { }
// Main class to run the program
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
System.out.println("Sum: " + calculator.add(5, 3));
}
}
Output
Sum: 8
Example: Final Method in a Class
In the code below, the start() method in the Vehicle class is declared as final, so it cannot be overridden by any subclass. Attempting to override it would result in a compilation error.
// Class with a final method
class Vehicle {
// Final method
final void start() {
System.out.println("Vehicle is starting...");
}
}
// Subclass attempting to override the final method (will cause an error)
// class Car extends Vehicle {
// void start() {
// System.out.println("Car is starting...");
// }
// }
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.start();
}
}
Output
Vehicle is starting...
Key Takeaways
An abstract class is meant to be a blueprint for other classes, with some methods left unimplemented.
A final class is used to prevent inheritance, keeping the class behaviour unchanged.
Abstract and final keywords serve opposite purposes and cannot be combined.
Advantages of Abstract Keyword
Defines a blueprint for subclasses: Allows creating a base structure for future development while letting subclasses provide specific implementations.
Encourages code reusability: Promotes sharing of common code among related classes by defining concrete methods in the abstract class.
Ensures a consistent structure: Enforces a common design by requiring subclasses to implement the abstract methods.
Supports partial implementation: Allows defining some methods in the abstract class while leaving others abstract for subclasses to implement.
Facilitates maintenance and extension: Makes it easier to update or extend the functionality by adding new subclasses that follow the defined structure.
Helps in achieving abstraction: Allows hiding unnecessary details and showing only the essential features to the user.
Use abstract classes when you need a base class: If you have a common structure with some shared code and some parts left for subclasses to implement, an abstract class is suitable.
Avoid making all methods abstract: Whenever the majority of the methods tend to provide the same implementation, it is advisable that the developers use an abstract class instead of an interface.
Do not use abstract with final or private methods: Abstract means that the method is going to be implemented in a subclass but the final method would never be extended. Furthermore, the private method can’t be accessed by the sub-classes.
Utilise abstract classes when there is a need to standardise certain behaviours: Abstract classes represent a conceptual idea that helps in fostering standardisation of related classes that may have slightly different implementations.
Avoid overusing abstract classes: Abstract classes should be used only when necessary. Overuse can make the codebase complex and harder to understand.
Document abstract methods well: Clearly describe the purpose and requirements of each abstract method so that subclasses know how to implement them correctly.
The abstract keyword in Java is extremely useful to developers in ensuring versatility when implementing code as well as maintenance. Developers are able to have a common foundation while leaving the behaviour for subclasses to implement. It is possible to achieve high levels of code organisation, lower redundancy and promote standardisation within related classes through the use of abstract methods and classes.
The abstract keyword strengthens the code and lowers the complexity when designing a structure or framework, encouraging code reuse. However, it’s important to understand its limitations and use it in the right situations to avoid unnecessary complexity. A thorough understanding of the best practices of abstract classes ensures a clean design and effectiveness of the model so that expansion can be further achieved without too much hassle. Want to explore Java in detail? Try Hero Vired’s Certificate Program in Application Development.
FAQs
What is the purpose of the abstract keyword in Java?
It is used to create abstract classes and methods that define a structure for subclasses.
Can an abstract class have a constructor in Java?
Yes, abstract classes can have constructors to initialise fields.
Can we instantiate an abstract class?
No, abstract classes cannot be instantiated directly.
Can an abstract class implement an interface?
Yes, abstract classes can implement interfaces but don’t have to implement all the methods.
Can an abstract method be declared as final?
No, abstract methods cannot be final, as they are meant to be overridden.
What happens if a subclass does not implement all abstract methods?
Hero Vired is a leading LearnTech company dedicated to offering cutting-edge programs in collaboration with top-tier global institutions. As part of the esteemed Hero Group, we are committed to revolutionizing the skill development landscape in India. Our programs, delivered by industry experts, are designed to empower professionals and students with the skills they need to thrive in today’s competitive job market.