When and why would you seal a class?
Object-Oriented Design practice on Codemia
Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.
Introduction
Sealing a class means preventing further inheritance from that class. It is a design choice used to protect invariants, simplify maintenance, and communicate intended extension points clearly. The right decision depends on API stability goals, correctness constraints, and framework behavior.
What Sealing Means in Practice
In languages such as C sharp, a sealed class cannot be inherited.
This enforces that behavior is fixed at this level.
In modern Java, sealed can allow only specific subclasses, which is a related but different model.
Why Seal a Class
Common reasons:
- Protect critical invariants.
- Prevent unsafe overrides.
- Simplify reasoning about behavior.
- Improve API clarity for consumers.
If subclassing can break guarantees, sealing is often the safest default.
Seal Classes with Security-Sensitive Logic
Classes handling authentication, crypto, or permission checks often benefit from sealing. Preventing override reduces risk of altered behavior through inheritance.
Example concept:
- Validation class should not allow subclass to bypass checks.
- Sealing ensures one audited implementation path.
This is not full security control by itself, but it reduces accidental extension risks.
Seal for Stable Value Objects
Immutable value objects often do not need subclassing. Sealing keeps equality and hash behavior predictable.
Predictable value semantics are easier when inheritance is blocked.
Performance and Runtime Considerations
In some runtimes, sealed classes can enable modest optimization opportunities because virtual dispatch paths are simpler. This should be treated as secondary benefit, not primary reason.
Design clarity and correctness are usually stronger justifications than micro-performance expectations.
When Not to Seal
Do not seal by default if class is intended as extension point for framework users or plugins. Sealing in that case can force brittle workarounds and reduce API usefulness.
Before sealing, ask:
- Should users customize behavior through inheritance.
- Is composition a better extension mechanism.
- Will this restriction break expected framework patterns.
A class can stay unsealed while still controlling extensibility with protected members and documented contracts.
Prefer Composition for Controlled Extensibility
Many teams seal concrete classes and expose interfaces for extension.
Consumers can provide alternate implementations without subclassing your concrete type.
Versioning and API Evolution
Sealing affects consumers. If class was inheritable and you seal it later, that is a breaking change for users who subclassed it.
For public libraries, decide sealing strategy early and document it. Stable extension contracts reduce upgrade friction.
Testing Implications
Sealed classes can limit mocking strategies that rely on subclass proxies in some test frameworks. If this matters, design around interfaces and dependency injection.
This keeps production behavior constrained while preserving testability.
Practical Decision Checklist
Seal a class when most answers are yes:
- Behavior must remain invariant.
- Inheritance adds risk without clear value.
- Public extension point is not intended.
- Composition via interface covers customization needs.
Using a checklist prevents ad hoc inconsistent design decisions.
Common Pitfalls
- Sealing everything without considering extension requirements.
- Leaving critical behavior unsealed where overrides can break invariants.
- Treating sealing as security guarantee on its own.
- Changing public class from unsealed to sealed in minor release.
- Ignoring testability impact when no interface abstraction exists.
Summary
- Sealing prevents inheritance and can protect class invariants.
- It is useful for stable, security-sensitive, or immutable behavior.
- Do not seal classes meant to be framework extension points.
- Prefer interface-based composition for controlled customization.
- Decide and document sealing policy early for API stability.
Related reading
- When do Java generics require ? extends T instead of T and is there any downside of switching?
- When should we use Observer and Observable?
- When to use abstract classes?
- Where do operations on models belong in Application Design Patterns?
- Where does Microsoft.Practices.ServiceLocation come from?
- Where to put Bean in Spring Boot?
- Which .NET Dependency Injection frameworks are worth looking into?
- Why are arrays covariant but generics are invariant?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Object-Oriented Design practice on Codemia
Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.