Sealed Classes and Interfaces – Object-Oriented Programming

5.15 Sealed Classes and Interfaces

Design by inheritance promotes code reuse in the OOP model—where subtypes can inherit code from their supertypes. Such an inheritance hierarchy is depicted in Figure 5.8, where the subclasses PrintedBook, Ebook, and Audiobook can inherit and reuse code from the superclass Book. The inheritance hierarchy of the Book superclass can also be regarded as a domain model for books (albeit greatly simplified for this exposition). However, this domain model as represented by the inheritance hierarchy in Figure 5.8 does not give the Book superclass much control over which classes can be classified as books. It can easily be exploited by clients to create their own subclasses of the Book superclass, thereby undermining the domain model represented by the inheritance hierarchy in Figure 5.8. If the PrintedBook subclass is not declared final, it can also be freely extended to define more kinds of books.

The superclass Book in Figure 5.8 cannot control which subclasses belong to the book domain, as it cannot control its extensibility. When it comes to domain modeling using inheritance, modifiers such as abstract and final are not adequate, nor are the accessibility modifiers to control the use of the superclass. In this section, we look at how sealed classes and interfaces aid in domain modeling that promotes accessibility of the superclass and allows control of extensibility of its subclasses. Sealed classes also have the additional benefits of resulting in secure hierarchies and aiding the compiler to provide better analysis of potential problems in the code.

Figure 5.8 A Domain Model as Represented by Inheritance Hierarchy

Sealed Classes

Sealing of classes and interfaces allows fine-grained control over the inheritance hierarchy of reference types in a given domain. A sealed class or interface only allows specific classes or interfaces to extend or implement its definition. To implement sealed classes, the language has introduced two new modifiers, sealed and non-sealed, and the permits clause—these three identifiers are contextual keywords that have special meaning only in the context of defining sealed types. As we shall see, the modifier final is also an integral part of defining sealed types.

We first look at sealed classes, and later we discuss sealed interfaces and compare the two (p. 315).

Going back to Figure 5.8 with the simplified domain model of books, we want to ensure that only the subclasses PrintedBook, Ebook, and Audiobook can directly extend the abstract superclass Book (i.e., ensure that the three subclasses are the only permitted direct subclasses of the sealed class Book). Figure 5.9 shows the modeling of the inheritance hierarchy with the required constraints. In this example, the classes involved are located in the same package. Skeletal code for the classes in shown in the discussion below, and complete class declarations can be found in Example 5.32.

Figure 5.9 Sealed Classes for Domain Modeling of Inheritance Hierarchy


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *