Sealed Classes
Why This Is Asked
Understanding class modifiers like sealed is key to robust object-oriented design. Interviewers want to know if you can explain how to prevent inheritance, why you would do it for performance or security, and how it relates to modern language features like records or pattern matching.
Key Concepts
- A
sealedclass cannot be inherited from. - It prevents the “Fragile Base Class” problem by stopping others from extending your logic.
- Performance: The compiler can perform “Devirtualization” because it knows no other class will override methods.
- Design: Used for utility classes, security-sensitive logic, or when a class is considered “complete.”
Answers by Technology
+ Add VariantExpected Answer (.NET 10 / C# 14)
In C#, the sealed modifier prevents a class from being inherited.
- Usage: You apply it to the class definition:
public sealed class MyClass { }. - When to use it:
- Performance: The JIT compiler can optimize calls to virtual members (Devirtualization) because it knows no overrides exist.
- Security: Prevents others from altering the behavior of your class by inheriting and overriding methods.
- Design Intent: When a class is designed as a “leaf” class and isn’t intended to be a base for others.
- Records: Records are often sealed to ensure value-based equality isn’t broken by inheritance.
Why It Matters
Using sealed by default is a common best practice in modern .NET development. It forces developers to favor composition over inheritance, which usually leads to cleaner designs. In high-performance systems, the micro-optimizations from devirtualization can add up.
Code Example
public sealed class CreditCardProcessor
{
public void Process(decimal amount)
{
// Critical logic that shouldn't be tampered with
}
}
// This would cause a compile-time error:
// public class MaliciousProcessor : CreditCardProcessor { }
Common Mistakes
- Sealing a base class: Preventing legitimate extension points in a framework.
- Forgetting to seal overrides: You can also seal specific overridden methods in a non-sealed class to prevent further redefinition:
public sealed override void SomeMethod().
Follow-up Questions
- Can a sealed class be abstract? (Answer: No, because an abstract class must be inherited to be instantiated, creating a logical contradiction).
- Does sealing affect memory? (Answer: Not directly, but it can reduce the size of the virtual method table (vtable) and enable better inlining).
Expected Answer (Java 26)
Java introduced Sealed Classes and Interfaces (Standard in Java 17, enhanced in subsequent versions) to provide more control over inheritance.
- Syntax:
public sealed class Shape permits Circle, Square { } - Keywords:
sealed,non-sealed,final,permits. - Why use it?:
- Restricted Hierarchy: You know exactly which classes can extend yours.
- Pattern Matching: The compiler can check if a
switchexpression over a sealed hierarchy is exhaustive, removing the need for adefaultcase. - Domain Modeling: Perfect for modeling data that belongs to a fixed set of types (Algebraic Data Types).
Why It Matters
Sealed classes bridge the gap between “anyone can extend” and “no one can extend” (final). They allow for better encapsulation of a class hierarchy, making the codebase more predictable and enabling powerful compiler-assisted features like pattern matching.
Code Example
public sealed interface Payment permits CreditCard, PayPal, Crypto {}
public record CreditCard(String number) implements Payment {}
public record PayPal(String email) implements Payment {}
public record Crypto(String wallet) implements Payment {}
public String getProvider(Payment p) {
return switch (p) {
case CreditCard c -> "Visa/Mastercard";
case PayPal pp -> "PayPal Inc.";
case Crypto cr -> "Blockchain";
// No default needed! Compiler knows all 'Payment' types.
};
}
Common Mistakes
- Omitting
permits: If subclasses are in the same file,permitsis optional. If they are in different files, it is mandatory. - Forgetting
non-sealed: Subclasses of a sealed class must be eitherfinal,sealed, ornon-sealed(opening the hierarchy back up).
Follow-up Questions
- Can a record be sealed? (Answer: Records are implicitly
final, so they cannot besealedthemselves, but they can implement asealedinterface). - Difference between Final and Sealed? (Answer: Final = 0 subclasses; Sealed = N specific subclasses).
Expected Answer (PHP 8.5)
PHP does not have a sealed keyword exactly like C# or Java. Instead, it uses final and readonly classes to control inheritance and state.
finalclass: Prevents any class from inheriting from it.final class MyClass {}.finalmethod: Prevents a specific method from being overridden in a child class.readonlyclass (PHP 8.2+): All properties are implicitlyreadonlyand inheritance is restricted such that children must also bereadonly.
Why It Matters
Using final by default is a common practice in modern PHP (e.g., in Doctrine entities or Domain services). It prevents the “Fragile Base Class” problem and ensures that your internal implementation details aren’t broken by unintentional inheritance.
Code Example
final class PaymentProcessor
{
public function execute(float $amount): void
{
// This logic cannot be overridden or inherited
}
}
// Fatal Error: Class MaliciousProcessor may not inherit from final class
// class MaliciousProcessor extends PaymentProcessor {}
Common Mistakes
- Sealing everything: Being too aggressive with
finalcan make it difficult for users of a library to mock or extend behavior when necessary. - Forgetting
finalon methods: If a class is not final, but you have a critical method that shouldn’t change, remember to mark the method asfinal.
Follow-up Questions
- Can an interface be final? (Answer: No. Interfaces are meant to be implemented).
- Readonly vs Final? (Answer:
finalstops inheritance;readonlystops property modification).