Abstraction in Java
Abstraction in Java
When you use a coffee machine, you press a single button and a coffee comes out. You never see, or need to see, the heating element, the water pump, or the pressure valve doing their work underneath. Abstraction brings that same idea into code: showing only what a user of a class needs to know, while hiding the internal machinery.
What is Abstraction?
Abstraction means hiding implementation details and exposing only the essential features an object needs to offer to the outside world. Where encapsulation (Chapter 4) focuses on protecting data from unwanted access, abstraction focuses on simplifying what a class shows about how it works.
In Java, abstraction is achieved in two main ways: abstract classes and interfaces. Both let you define what a class must be able to do, without necessarily saying how it does it, leaving that detail to be filled in later.
Abstract Classes in Java
An abstract class is a class that cannot be instantiated on its own, you can never write new Shape() if Shape is abstract. It exists purely to be extended, and it can contain a mix of fully implemented methods and abstract methods, methods that have a signature but no body, which every subclass is forced to implement.
abstract class Shape {
String colour = "unknown";
// Abstract method — no body, subclasses must implement it
abstract double area();
// Regular method — already implemented, inherited as-is
void displayColour() {
System.out.println("Colour: " + colour);
}
}
class Circle extends Shape {
double radius;
Circle(double r) {
radius = r;
}
@Override
double area() {
return Math.PI * radius * radius;
}
}
public class Main {
public static void main(String[] args) {
Circle c = new Circle(5);
System.out.println(c.area()); // 78.53...
c.displayColour(); // Colour: unknown
}
}
Shape defines that every shape must be able to report an area(), but it deliberately leaves the formula undefined, since a circle and a rectangle calculate area completely differently. Any class extending Shape is forced by the compiler to override area(), or it must also be declared abstract itself.
Interfaces in Java
An interface takes abstraction a step further. Traditionally, it could only declare method signatures, no implementation at all, leaving every single method to be filled in by whichever class implements it. A class uses the implements keyword to take on an interface's contract.
interface Drawable {
void draw(); // no body — purely a contract
}
class Square implements Drawable {
@Override
public void draw() {
System.out.println("Drawing a square");
}
}
class Triangle implements Drawable {
@Override
public void draw() {
System.out.println("Drawing a triangle");
}
}
public class Main {
public static void main(String[] args) {
Drawable shape1 = new Square();
Drawable shape2 = new Triangle();
shape1.draw(); // Drawing a square
shape2.draw(); // Drawing a triangle
}
}
Because Java does not allow a class to extend more than one class, but does allow a class to implement multiple interfaces at once, interfaces are also how Java achieves something close to multiple inheritance, a class can promise to fulfil several different contracts simultaneously.
• A class can implement any number of interfaces, separated by commas after the implements keyword.
• Since Java 8, interfaces can also include default methods, which do provide a method body, giving implementing classes a ready-made behaviour they can use as-is or override.
• Interface fields are implicitly public, static, and final, meaning they behave as shared constants, not per-object data.
Abstract Class vs Interface
Aspect | Abstract Class | Interface |
Keyword used | extends | implements |
Number a class can use | Only one (single inheritance) | Many, at the same time |
Method bodies allowed | Yes, can mix abstract and fully implemented methods | Yes, via default and static methods (Java 8+), alongside abstract ones |
Fields | Can have any kind of field, with any access modifier | Fields are implicitly public, static, and final |
Constructors | Allowed (used by subclasses via super()) | Not allowed |
Best used when | Classes share significant common code, not just a contract | Unrelated classes need to promise the same capability |
Did You Know?
Choosing between an abstract class and an interface often comes down to one question: do these classes share meaningful implementation, or just a shared promise of behaviour? If several classes need to reuse the same field or method body, an abstract class saves duplication. If you only need to guarantee that unrelated classes can all do the same thing, an interface is the leaner choice.










