Lesson 18: Sealed Classes (sealed, permits) – Java 15+

Java 15 introduced Sealed Classes, which allow you to control which classes can extend or implement a class or interface. This feature improves encapsulation, security, and maintainability in Java applications.


1. What Are Sealed Classes?

Sealed classes restrict inheritance, so only specific subclasses can extend them.
Prevent unwanted extensions, improving code security and maintainability.
Useful for defining fixed hierarchies, like shapes (Circle, Square) or permissions (Admin, User).


2. How to Define a Sealed Class?

📌 Syntax of Sealed Classes

sealed class A permits B, C { } // A can ONLY be extended by B and C

final class B extends A { }      // ✅ Allowed (Final means no further extension)
non-sealed class C extends A { } // ✅ Allowed (C can be extended further)

A “sealed” class explicitly declares which subclasses are permitted.


3. Example: Restricting Subclasses in a Sealed Hierarchy

📌 Problem: Only Circle and Square should be allowed to extend Shape.

🟢 Java 15+ Sealed Class Solution

sealed class Shape permits Circle, Square { } // Only Circle & Square can extend

final class Circle extends Shape { } // ✅ Allowed (final: No more extensions)
final class Square extends Shape { } // ✅ Allowed

🚨 What’s NOT allowed?

class Triangle extends Shape { } // ❌ ERROR: Not permitted!

Prevents unauthorized subclasses!


4. Types of Subclasses Allowed in a Sealed Class

A subclass of a sealed class MUST be one of these types:

ModifierBehavior
finalThe subclass cannot be extended further.
sealedThe subclass must define its own permitted subclasses.
non-sealedThe subclass removes all restrictions, allowing anyone to extend it.

📌 Example: Using final, sealed, and non-sealed

sealed class Vehicle permits Car, Bike { }

final class Car extends Vehicle { } // ✅ No more extensions

sealed class Bike extends Vehicle permits ElectricBike { } // ✅ Must specify its own subclasses

non-sealed class ElectricBike extends Bike { } // ✅ No restrictions, anyone can extend

Flexible but controlled inheritance!


5. Comparison: Before Java 15 vs. Java 15+ (sealed)

FeatureBefore Java 15Java 15+ (sealed)
Restricting subclasses❌ Not possible✅ Explicitly define permitted subclasses
Preventing unintended inheritance❌ Any class can extend another✅ Only permitted subclasses allowed
Security & Maintainability❌ Difficult to control✅ Safer and easier to maintain

6. When Should You Use Sealed Classes?

🚀 Use sealed when:
✔ You want strict control over a class hierarchy (e.g., Shapes, User Roles).
✔ You want to prevent accidental extensions of a class.
✔ You want better security and maintainability in a large application.

🚨 Don’t use sealed if:
❌ You want to allow any class to extend the base class.
❌ You don’t need strict control over subclassing.


Lesson Reflection

  1. Why do Sealed Classes improve security and maintainability?
  2. When should you use sealed, final, and non-sealed in a class hierarchy?
  3. What happens if a class tries to extend a sealed class without permission?

Answers to Reflection Questions on Sealed Classes (sealed, permits)


1️⃣ Why do Sealed Classes improve security and maintainability?

They prevent unauthorized extensions, making the code more predictable and secure.
They enforce a controlled hierarchy, ensuring only intended subclasses exist.
They help with maintainability, as developers can clearly see which classes can extend a sealed class.

📌 Example: Preventing Unwanted Inheritance

sealed class Payment permits CreditCard, PayPal { }

final class CreditCard extends Payment { } // ✅ Allowed (Final: No further extensions)
final class PayPal extends Payment { }    // ✅ Allowed

🚨 What happens if another class tries to extend Payment?

class Bitcoin extends Payment { } // ❌ ERROR: Bitcoin is NOT permitted!

Prevents unauthorized subclasses, improving security.


2️⃣ When should you use sealed, final, and non-sealed in a class hierarchy?

ModifierUse When…Example
sealedYou want to restrict which classes can extend a base class.sealed class Animal permits Dog, Cat { }
finalYou want to prevent further extension of a subclass.final class Dog extends Animal { }
non-sealedYou want to allow unrestricted inheritance after a class is already sealed.non-sealed class Cat extends Animal { }

📌 Example: Choosing sealed, final, and non-sealed Wisely

sealed class Animal permits Dog, Cat { }  // Only Dog & Cat are allowed

final class Dog extends Animal { } // ✅ No more extensions

non-sealed class Cat extends Animal { } // ✅ Other classes can extend Cat

Use sealed for control, final to prevent further inheritance, and non-sealed for flexibility.


3️⃣ What happens if a class tries to extend a sealed class without permission?

🚨 The Java compiler throws an error!
If a class that is not listed in permits tries to extend a sealed class, Java prevents compilation.

📌 Example: Illegal Extension of a Sealed Class

sealed class Vehicle permits Car, Bike { }

final class Car extends Vehicle { } // ✅ Allowed
final class Bike extends Vehicle { } // ✅ Allowed

class Truck extends Vehicle { } // ❌ ERROR: Truck is NOT permitted!

Compiler Error Message:

error: class Truck is not allowed to extend sealed class Vehicle

This ensures that only approved subclasses exist, improving maintainability.


🔍 Key Takeaways

Sealed classes restrict inheritance, preventing unintended extensions.
Use sealed to control subclassing, final to prevent further extension, and non-sealed for flexibility.
If an unauthorized class tries to extend a sealed class, the compiler throws an error.

The next Java 16+ feature: Records (record keyword for immutable data classes) 😊🚀

Java Sleep