Within the realm of Java programming, abstract classes play a pivotal role in outlining the design and actions of classes situated in an inheritance hierarchy. They serve as a template for additional classes, allowing for the declaration of certain methods without specifying their functionality. In the upcoming section, we will delve into the essence of abstract classes, exploring their characteristics, benefits, and instances.
Prior to delving into abstract classes in Java, it is essential to have a clear grasp of the abstraction concept.
What is Abstraction in Java?
Abstraction involves concealing the specifics of implementation and revealing solely the necessary functionality to users. Essentially, it showcases only the vital characteristics while keeping internal details hidden.
For instance, in the case of sending a text message, we compose the message and send it off without detailed knowledge of the internal processing and delivery mechanisms.
Abstraction enables you to concentrate on the actions performed by an object rather than the specific implementation details of those actions.
In Java, abstraction can be accomplished through two methods:
- By utilizing an Abstract Class, which offers a range of abstraction from 0% to 100%.
- Through the use of an Interface, which provides complete 100% abstraction.
What is Abstract Class in Java?
In Java, a class that is defined with the abstract keyword is referred to as an abstract class. This type of class is capable of including both abstract methods (methods lacking implementation) and concrete methods (methods with implementation).
An abstract class offers partial abstraction in programming. It is designed to be a parent class and cannot be instantiated independently. By establishing a common structure and shared behavior, it allows child classes to implement their unique functionalities. Abstract methods lack implementations and are required to be defined by the subclasses.
Points to Remember
- An abstract class must be declared with an abstract keyword.
- It can have abstract and non-abstract methods.
- It cannot be instantiated.
- It can have constructors and static methods also.
- It can have final methods which will force the subclass not to change the body of the method.
Creating / Declaring an Abstract Class
The abstract keyword is utilized to create an abstract class, which serves as a base class and cannot be directly instantiated.
Syntax
Here is the syntax to create an abstract class:
public abstract class Shape {
public abstract double area();
public void display() {
System.out.println("This is a shape.");
}
}
In the provided instance, the class Shape is defined as an abstract class. It includes an abstract method area, which lacks a body, and a concrete method display that has an implementation. Any derived class of Shape is required to define the area method, but it can utilize the display method directly.
Abstract Method
An abstract method is a method declared with the abstract keyword that does not contain an implementation, also known as a method body.
Example
Here is a demonstration of what an abstract method typically appears as:
abstract void printStatus(); // no method body
An abstract method merely defines the method's structure, leaving the actual implementation to be supplied by the subclass extending the abstract class.
Abstract Class with an Abstract Method
Below is a demonstration of an abstract class featuring an abstract method that subclasses are required to implement.
In this scenario, "Bike" is depicted as an abstract class featuring the abstract function named run. The subclass "Honda" is responsible for executing the run method, showcasing the concept of abstract classes outlining method frameworks and delegating specific implementations to subclasses.
Example
//Creating an abstract class having abstract method
abstract class Bike{
abstract void run();
}
//Creating a child class and override abstract method
class Honda extends Bike{
void run(){System.out.println("running safely");}
}
//Creating a Main class to create object and call methods
public class Main{
public static void main(String args[]){
Bike obj = new Honda();
obj.run();
}
}
Output:
running safely
More Examples of Abstract Class
To enhance your comprehension of abstract classes and their utilization in Java, work through the subsequent instances:
Example 1: Shape Abstract Class
In the provided instance, the class Shape is abstract and is implemented by the classes Rectangle and Circle. The detailed implementation is typically concealed from the user and can be accessed via a factory method.
Example
abstract class Shape{
abstract void draw();
}
//In real scenario, implementation is provided by others i.e. unknown by end user
class Rectangle extends Shape{
void draw(){System.out.println("drawing rectangle");}
}
class Circle extends Shape{
void draw(){System.out.println("drawing circle");}
}
//In real scenario, method is called by programmer or user
public class Main{
public static void main(String args[]){
//In a real scenario, object is provided through method, e.g., getShape() method
Shape s=new Circle();
s.draw();
}
}
Output:
drawing circle
Example 2: Bank Abstract Class
This illustration demonstrates the utilization of abstract classes to establish a shared interface for interconnected classes, where each subclass offers its unique implementation.
Example
abstract class Bank{
abstract int getRateOfInterest();
}
class SBI extends Bank{
int getRateOfInterest(){return 7;}
}
class PNB extends Bank{
int getRateOfInterest(){return 8;}
}
public class Main{
public static void main(String args[]){
Bank b;
b=new SBI();
System.out.println("Rate of Interest is: "+b.getRateOfInterest()+" %");
b=new PNB();
System.out.println("Rate of Interest is: "+b.getRateOfInterest()+" %");
}
}
Output:
Rate of Interest is: 7 %
Rate of Interest is: 8 %
Abstract Class having Constructor, Data Members, and Methods
In Java, an abstract class is capable of including data fields, abstract methods, non-abstract methods, constructors, and even the main method.
Example
The following example shows an abstract class Bike with:
- A constructor that runs when an object of the subclass is created.
- An abstract method run that must be implemented by subclasses.
- A concrete method changeGear that can be inherited as-is.
Example
//Example of an abstract class that has abstract and non-abstract methods
abstract class Bike{
Bike(){System.out.println("bike is created");}
abstract void run();
void changeGear(){System.out.println("gear changed");}
}
//Creating a Child class which inherits Abstract class
class Honda extends Bike{
void run(){System.out.println("running safely..");}
}
//Creating a Main class which calls abstract and non-abstract methods
public class Main{
public static void main(String args[]){
Bike obj = new Honda();
obj.run();
obj.changeGear();
}
}
Output:
bike is created
running safely..
gear changed
If a class includes a method that is abstract, the class must also be marked as abstract.
class Bike12 {
abstract void run();
}
Output:
compile time error
- When a subclass inherits from an abstract class that contains abstract methods, it is required to either provide implementations for all the abstract methods or designate itself as abstract as well.
abstract class Vehicle {
abstract void start();
}
// Subclass not implementing abstract method must be abstract
abstract class Car extends Vehicle {
}
// Subclass implementing abstract method can be instantiated
class Honda extends Vehicle {
void start() {
System.out.println("Honda started");
}
}
public class Main {
public static void main(String[] args) {
Vehicle v = new Honda();
v.start(); // Output: Honda started
}
}
Output:
Honda started
Another Real Scenario of Abstract Class
An abstract class can be utilized to offer partial implementation of an interface. This approach allows the user flexibility by not requiring them to override every method within the interface.
Note: If we are beginner to Java, learn interface first then see this example.
Example
interface A{
void a();
void b();
void c();
void d();
}
abstract class B implements A{
public void c(){System.out.println("I am c");}
}
class M extends B{
public void a(){System.out.println("I am a");}
public void b(){System.out.println("I am b");}
public void d(){System.out.println("I am d");}
}
public class Main{
public static void main(String args[]){
A a=new M();
a.a();
a.b();
a.c();
a.d();
}
}
Output:
I am a
I am b
I am c
I am d