Abstraction focuses on what an object does instead of how it does it.
Abstraction allows us to focus on what an object does instead of how it does. We can achieve abstraction with abstract methods, we can create abstract methods in abstract classes and interfaces. When abstraction is used there is a contract between abstraction and its concrete classes that forces concrete classes to have specific behaviors driven from abstraction.
- Abstract class.
- Interface.
Abstract class
- An abstract class is a special class in Java that can have abstract methods.
- We cannot initialize abstract classes directly.
- The abstract class can have regular methods and properties as well.
- If an abstract class extends another abstract class but the implementation of abstract methods is not required.
- The first non-abstract class that extends the abstract class must implement all its abstract methods.
- The class can extend only one abstract class by the rules of inheritance to avoid the diamond problem.
public abstract class Vehicle{
public String name;
public abstract void drive();
public abstract void stop();
}
We have an abstract class Vehicle with two abstract methods move and stop. All vehicles should be able to move and stop but the way they do will be different and based on concrete class implementation.
public class Car extends Vehicle {
@Override
public void drive() {
System.out.println("Car is driving");
}
@Override
public void stop() {
System.out.println("Car is stopped");
}
}
In the above example, Car
class is extending the Vehicle
abstract class. The Car
class is a concrete class and it must implement all abstract methods from Vehicle
class. It’s kind of agreement for the Car
class with the abstract class so if Car wants to be a Vehicle. It should have implemented the abstract methods of Vehicle.
We implement abstract methods by overriding them.
Overriding rules:
1. the method name should be same.
2. the number, order, and data type of argument should be same. Data type can be covariant as well.
3. access modifier should be same or more accessible.
4. if overriding method throws exception in the method declaration. Exception should be same or smaller(child exceptions) than parent’s class method or no exception at all.
Let’s have another concrete class
public class Motorcycle extends Vehicle {
@Override
public void drive() {
System.out.println("Motorcycle is driving");
}
@Override
public void stop() {
System.out.println("Motorcycle is stopped");
}}
We have another class that extends our abstract Vehicle class and implements its abstract methods.
Why do we need to create abstract classes and then create regular classes that extend them? Why just don’t create two regular classes?
The code should be designed to make changes easier. There is one powerful OOP principle — code to the interface, not to concrete classes. When we say interface we are referring to abstraction. Let’s see an example
public class Main {
public static void main(String[] args) {
// we cannot assign abstract class directly
// Vehicle vehicle = new Vehicle();
Vehicle vehicle = new Car();
vehicle.drive();
// a lot of code here ...
vehicle.stop();
}
}
We cannot initialize abstract class directly so it’s not useful by itself and always needs to be used with concrete classes.
Let’s say we have a program that responsible to drive a vehicle to a specific destination. Now, business wants to add Motorcycle. If we wouldn’t use an abstract class and code them differently with different method names and overall differently. We had to write a new program for Motorcycle. Luckily we coded to abstraction and we can just change one line.
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new Motorcycle();
vehicle.drive();
// a lot of code here ...
vehicle.stop();
}
}
Interface
- The interface can have only abstract methods except for static and default methods.
- We cannot initialize the interface directly.
- All interface properties are
public static final
. Basically, they are all constants by default. public static final
is optional to type for properties. It will be injected by default.public abstract
is optional to type for methods in the interface. It will be injected by default.- We need to use
implements
keyword to implement our interface. One class can implement multiple interfaces. static
anddefault
methods can have bodies in the interface.
Let’s see the same example as with abstract class
public interface Vehicle {
public static final String str;
// private String str1; does not compile void drive(); // public abstract will be injected by default
void stop(); // public abstract will be injected by default // static method can have a body
public static String setStr(String strInput) {
str = strInput;
} // default method can have a body
public default void printStr() {
System.out.println(str);
}
}
Above we have our interface. I have added extra code to show you some details about the default public static final
properties and two methods that can have bodies.
public class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Car is driving");
}
@Override
public void stop() {
System.out.println("Car is stopped");
}
}
We created our first concrete class for our interface. We use implements
keyword in order to implement our interface.
public class Motorcycle implements Vehicle {
@Override
public void drive() {
System.out.println("Motorcycle is driving");
}
@Override
public void stop() {
System.out.println("Motorcycle is stopped");
}}
And another concreate class.
public class Main {
public static void main(String[] args) {
// we cannot assign interface directly
// Vehicle vehicle = new Vehicle();
Vehicle vehicle = new Car();
vehicle.drive();
// a lot of code here ...
vehicle.stop();
}
}
We cannot initialize interfaces directly so they are not useful at all without concrete classes.
That’s it about abstraction in Java. Have a good day!
Please take my Java Course for video lectures.This article is part of the series of articles to learn Java programming language from Tech Lead Academy:Introduction to programming
OS, File, and File System
Working with terminal
Welcome to Java Programming Language
Variables and Primitives in Java
Convert String to numeric data type
Input from the terminal in Java
Methods with Java
Java Math Operators and special operators
Conditional branching in Java
Switch statement in Java
Ternary operator in Java
Enum in Java
String class and its methods in Java
Loops in Java
Access modifiers in Java
Static keyword in Java
The final keyword in Java
Class and Object in Java
Object-Oriented Programming in Java
OOP: Encapsulation in Java
OOP: Inheritance in Java
OOP: Abstraction in Java
OOP: Polymorphism in Java
The method Overriding vs Overloading in Java
Array in Java
Data Structures with Java
Collection framework in Java
ArrayList in Java
Set in Java
Map in Java
Date and Time in Java
Exception in Java
How to work with files in Java
Design Patterns
Generics in Java
Multithreading in java
Annotations in Java
Reflection in Java
Reflection & Annotations - The Powerful Combination
Run terminal commands from Java
Lambda in Java
Unit Testing in Java
Big O Notation for coding interviews
Top Java coding interview questions for SDET