Sealed classes allow you to control which classes can extend (inherit from) a certain class. Think of it as a way to create a list of approved subclasses.
Before Java 17, there was no built-in way to restrict which classes could inherit from another class. This could lead to confusion and unexpected behavior in your code. Sealed classes make this restriction clear and enforceable.
sealed
Keyword: You declare a class as sealed using the sealed
keyword.permits
clause.Let’s use a simple analogy to explain this. Imagine you have a Shape and you only want certain shapes (like Circle and Square) to be recognized as valid shapes.
// This is the sealed class
public abstract sealed class Shape permits Circle, Square {
public abstract double area(); // Abstract method to calculate area
}
// This class can be created but cannot be extended further
public final class Circle extends Shape {
private final double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius; // Area of circle
}
}
// This class can also be created but cannot be extended further
public final class Square extends Shape {
private final double side;
public Square(double side) {
this.side = side;
}
@Override
public double area() {
return side * side; // Area of square
}
}
// This class can be extended further
public non-sealed class Triangle extends Shape {
private final double base;
private final double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public double area() {
return 0.5 * base * height; // Area of triangle
}
}
Circle
, Square
, or Triangle
.final
, meaning no one can create a class that extends them.non-sealed
, so other classes can still extend it if needed.Shape
.
Before Java 17: No clear way to control inheritance; could lead to confusion.
After Java 17: Sealed classes give you clear control over which classes can extend others, making your code easier to understand and maintain.