Abstraction in Java


Abstraction is another important OOP's principle in Java. It is the process of hiding internal implementation details from the user and providing only necessary functionality to the users. It removes all non-essential things and shows only important things to users.

In other words, Abstraction in Java is a technique by which we can hide the data that is not required to a user. It hides all unwanted data so that users can work only with the required data. Let's take real-time examples to understand the concept of abstraction in java.

Realtime Examples of Abstraction in Java


1. Let's first take ATM machine as a real-time example. We all use an ATM machine for cash withdrawal, money transfer, retrieve min-statement, etc in our daily life. But we don't know internally what things are happening inside ATM machine when you insert ATM card for performing any kind of operations.

2. Let's understand another real-time example. A car owner knows how to drive it. He knows about various components of car and how to use them. For example, a car owner knows that the accelerator pedal is used to increase the speed of car and pressing the brake pedal stops it. To perform these simple actions, you only need to know how to use these components but not need to know how they function.

3. When you need to send SMS  from your mobile, you only type the text and send the message. But you don't know the internal processing about the message delivery.

Thus, there are lots of such important things in real life that shows abstraction. Similarly, happen in OOP. You only need to call the specific classes or methods to implement specific program logic but you don't know how these classes or methods function. This concept is known as abstraction in java.

How to achieve Abstraction in Java?


There are two ways to achieve abstraction in java. They are as follows:
1. Abstract class (0 to 100%)
2. Interface (100%)

Abstract Class in Java


An abstract class is a class, which is declared with abstract keyword. It is just like a normal class but has two differences. 
1. We cannot create an object of this class. Only objects of its non-abstract (or concrete) sub-classes can be created. 
2. It can have zero or more abstract methods which are not allowed in a non-abstract class (concrete class).
Key points:
1. Abstract is a non-access modifier in java which is applicable for classes, interfaces, methods, and inner classes. It represents an incomplete class which depends on subclasses for its implementation. Creating subclass is compulsory for abstract class.
2. A non-abstract class is sometimes called a concrete class.
3. An abstract concept is not applicable to variables.

Abstract Method in Java


A method which is declared with abstract modifier and has no implementation (means no body) is called an abstract method in java. It does not contain any body. It has simply a signature declaration followed by a semicolon. It has the following general form as given below.
Syntax: 
    abstract type MethodName(arguments); // No body
For example:
    abstract void msg(); // No body.
Since the abstract method does not contain any body. Therefore, it is also known as an incomplete method in java.
A non-abstract class cannot have an abstract method whether it is inherited or declared. In Java.

Key points:
1. Abstract method cannot be static.
2. It cannot be private because the abstract method must be implemented in the subclass. If we declare it as private, we cannot implement it from outside the class.
3. A concrete method is a method which has always the body. It is also called a complete method in java.

When to Use Abstract class & Abstract method in Java?


Uses of abstract method in Java:
1. An abstract method can be used when the same method has to perform different tasks depending on the object calling it.
2. A method can be used as abstract when you need to be overridden in its non-abstract subclasses.

Use of abstract class in Java: 
1. An abstract class can be used when we need to share the same method to all non-abstract subclasses with their own specific implementations.
Let's understand these concepts with a suitable example program.

When we write anything in a class, it is applicable to all its objects. If a method is defined in a class, it is available to all objects of a class. For example, suppose a class MyTest that contains a method calculate() that calculates addition of a given two numbers. If you create three objects to this class, all three objects will get a copy of this method and from any object, we can call this method. Here, the requirement of all objects is the same i.e, to calculate addition of two numbers.

Now, our requirement is changed. We want that first object calculates addition, second object calculates subtraction, and the third object calculates multiplication. Since calculate() method has to perform three different tasks depending on the object. In such a case, how will write calculate() method in MyTest? 

If we declare three methods like add(), sub(), and multiply() in MyTest, all three methods will be available for all three objects which are not advisable.
To solve this problem, we will use an abstract class and abstract method. We will declare calculate() method as abstract, it will not has any body within it. Now, we will derive three subclasses like Addition, Subtraction, and Multiplication from class MyTest wherein each subclass, we will provide a body for calculate() method so that it can calculate add, subtract, and multiply. 

In this way, the same abstract method will be implemented in three subclasses as per the requirement of objects and can perform different tasks. We can also create objects of subclasses and respective method can be called using these objects. The hierarchy is shown in the below figure.
use of Abstract class in Java
Program source code 1: Let's us create a program where abstract class MyTest has one abstract method which has various implementation in subclasses.
    package com.abstraction; public abstract class MyTest { abstract void calculate(int a, int b); // No body. } public class Addition extends MyTest { void calculate(int a, int b){ int x=a+b; System.out.println("Sum: " +x); } } public class Subtraction extends MyTest { void calculate(int a, int b){ int y=a-b; System.out.println("Subtract: " +y); } } public class Multiplication extends MyTest { void calculate(int a, int b){ int z=a*b; System.out.println("Multiply: " +z); } } public class MyClass { public static void main(String[] args) { Addition a=new Addition(); Subtraction s=new Subtraction(); Multiplication m=new Multiplication(); a.calculate(20, 30); s.calculate(10, 5); m.calculate(10, 20); } }
    Output: Sum: 50 Subtract: 5 Multiply: 200
As you can see in the above example, the requirement of every object has been fulfilled.

Features of Abstract class in Java


There are following important features of abstract class in Java.
1. Abstract class is not a pure abstraction in java.
2. In Java, object creation is not possible for an abstract class because It is partially implemented class, not fully implemented class.
3. It can be abstract even without any abstract method

4. It can have one or more abstract methods or non-abstract methods (or concrete methods) or combination of both methods.
5. Abstract class allows to define private, final, static and concrete methods. Everything is possible to define in an abstract class as per application requirement.

6. It can have constructors.
7.  Abstract class does not support multiple inheritance in java but allow in interfaces.
8. It can implement one or more interfaces in java.

Rules of Abstract class in Java


1. Class must be declared with abstract keyword to make an abstract class.
2. We cannot instantiate an abstract class but we can create object of subclass of the abstract class provided they must implement abstract method.
3. If any method is abstract in a class, the class must be declared as abstract. 

4. To use methods declared in an abstract class, the abstract class must be extended by an ordinary class and must implement (override) all abstract methods in that ordinary class. 


5. If a new abstract method is added in the abstract class, all non-abstract subclass which extends that abstract class, must implement the newly added abstract method. If it does not implement all the abstract method, the class must be declared as abstract.

6. If a new instance method is added in the abstract class, all non-abstract subclass which extends that abstract class, is not necessary to implement newly added instance method.
7. Inside the abstract class, we can create any number of constructors. If you do not create a constructor, the compiler will create a default constructor.
Let's see example programs based on these rules to understand the abstract class concept more clearly.

Java Abstract Class Example Programs


Program source code 2: Let us make a program where we will try to create an object of abstract class but the compiler will show a compile-time error. 
    package com.abstraction; public abstract class AbsClass { // No abstract method here. } // Creating a subclass which inherits Abstract class. public class Subclass extends AbsClass { public static void main(String[] args) { AbsClass c=new AbsClass(); // Compile-time error. } }
    Output: Unresolved compilation problem: Cannot instantiate the type AbsClass
Program source code 3: Let us make a program where an abstract class Hello contains both abstract method and instance method. The abstract method "msg2" will be implemented in Test class that extends a class Hello.
    package com.abstraction; public abstract class Hello { // Declaration of instance method. public void msg1() { System.out.println("msg1-Hello"); } abstract public void msg2(); } public class Test extends Hello { // Overriding abstract method. public void msg2() { System.out.println("msg2-Test"); } public static void main(String[] args){ // Creating object of subclass Test. Test obj=new Test(); obj.msg1(); obj.msg2(); } }
    Output: msg1-Hello msg2-Test
In this example program, we have not implemented instance method msg1() in subclass but abstract method msg2() has been implemented (overridden) in the subclass.

Program source code 4: Let's make a program where an abstract class can have a data member, constructor, abstract, final, static, and instance method (non-abstract method).
    package com.abstraction; public abstract class AbstractClass { int x=10; // Data member. AbstractClass(){ System.out.println("AbstractClass constructor"); } final void m1(){ System.out.println("Final method"); } void m2(){ System.out.println("Instance method"); } static void m3(){ System.out.println("Static method"); } abstract void msg(); } public class AbsTest extends AbstractClass { AbsTest(){ System.out.println("AbsTest class constructor"); } void msg(){ System.out.println("Hello Java"); } public static void main(String[] args) { AbsTest t=new AbsTest(); t.msg(); t.m1(); t.m2(); m3(); System.out.println("x= " +t.x); } }
    Output: AbstractClass constructor AbsTest class constructor Hello Java Final method Instance method Static method x= 10
In this example program, after object creation, the constructor of non-abstract subclass will be called immediately. In the first line of constructor, internally super will call the constructor of an abstract class. The control of execution will be immediately transferred to the constructor of abstract class.
Therefore, the first output is "AbstractClass constructor". After executing abstract class constructor, control of execution again comes to execute subclass constructor. The second output is "AbsTest class constructor".

Why abstract class has constructor even though you cannot create an object?


We cannot create an object of abstract class but we can create an object of subclass of abstract class. When we create an object of subclass of an abstract class, it calls the constructor of subclass. This subclass constructor has super in the first line that calls constructor of an abstract class. Thus, the constructors of an abstract class are used from constructor of its subclass. 
If the abstract class doesn't have constructor, a class that extends that abstract class will not get compiled.

Let's understand this concept with an example program in a better way.
Program source code 5: Let's create a program where an abstract class Employee contains instance variables, constructor, and concrete method. A subclass Engineer extends abstract class Employee.
    package com.abstraction; public abstract class Employee { private String name; private int id; public Employee(String name, int id){ this.name=name; this.id=id; } // Declaration of concrete method. void m1(){ System.out.println("Name: " +name); System.out.println("Id: " +id); } } public class Engineer extends Employee { public Engineer(String name, int id){ super(name, id); // This statement is used to call super class constructor. } public static void main(String[] args){ // Creating an object of the subclass of abstract class. Engineer e=new Engineer("Deep", 10202); e.m1(); } }
    Output: Name: Deep Id: 10202
Now consider the above program. When we have created an object of subclass, it immediately calls Engineer class constructor. In the first line of constructor, super keyword calls the superclass constructor (Employee). Thus, the superclass constructor is executing when creating an object of subclass. By executing this superclass constructor, JVM is initializing to non-static variables name and id in the abstract class.

Now suppose if abstract class does not allow to define constructor, in such a case, is it possible to initialize the value of non-static variables in abstract class? No, because without object creation of abstract class, we cannot initialize non-static variables. Therefore,  an abstract class allows constructors to initialize variables.

Program source code 6: Let us create a program in which an abstract class reference refers to the subclass objects. Abstract class reference can be used to call methods of the subclass.
    package Abstarctclass; public abstract class Identity { abstract void getName(String name); abstract void getGender(String gender); abstract void getCity(String city); } public class Person extends Identity { void getName(String name) { System.out.println("Name : " +name); } void getGender(String gender) { System.out.println("Gender : " +gender); } void getCity(String city){ System.out.println("City: " +city); } // Newly added method in subclass. void getCountry(String country){ System.out.println("Country: " +country); } } public class Mainclass { public static void main(String[] args) { // Declaring abstract class reference equal to subclass objects. Identity i=new Person(); i.getName("DEEPAK"); i.getGender("MALE"); i.getCity("DHANBAD"); // i.getCountry("INDIA"); // Compile-time error because we cannot access newly added method in subclass using superclass reference. } }
    Output: Name: DEEPAK Gender: MALE City: DHANBAD
In the preceding program, we created abstract class reference that refers to its subclass objects. Using superclass reference, we are accessing all methods of subclass in the main() method excepting newly added method in the subclass. But if it is possible to access all the members of subclasses by creating objects of subclass then,

Why should we create a reference to the superclass (abstract class reference)? 


We should create a reference of the superclass to access subclass features because superclass reference allows only to access those features of subclass which have already declared in superclass. If you create an individual method in subclass, the superclass reference cannot access that method.
Thus, any programmer cannot add their own additional features in subclasses other than whatever is given in superclass.

Advantages of Abstract class in Java


The main advantages of using abstract class are as follows:
1. Abstract class makes programming better and more flexible by giving the scope of implementing abstract methods.
2. Programmer can implement abstract method to perform different tasks depending on the need. 
3. We can easily manage code.

Final words 
Hope that this tutorial has covered almost all important points related to abstraction and abstract class in java with real-time example programs. I hope that you will have understood and enjoyed this topic.
Thanks for reading!