Abstract Classes and Interfaces
So far, we have looked at ordinary classes, sometimes referred to as “concrete” classes. You can have classes in a hierarchy, where an open
class can be extended by subclasses. However, while a class can declare what is open
to be overridden, a concrete class cannot stipulate something that must be implemented in a subclass. While a subclass can elect to override an open
function, it does not have to do so.
Abstract classes and interfaces offer two ways to provide “contracts” between classes and their subclasses. These work similar to their Java counterparts, allowing you to declare functions with no default implementation, where the subclass is required by the compiler to provide an implementation.
The Objective: Contracts
Sometimes, we want to be able to get information about an object, but where the type of the object does not have a way of knowing that information.
For example, let’s go back to the class hierarchy that we saw in the chapter on classes, adding in one more species:
open class Animal
class Frog : Animal()
class Axolotl : Animal()
class KomodoDragon : Animal()
We might want to know if an Animal
has gills. Whether any given type of Animal
has gills depends partly on the species and partly on circumstances:
- A Komodo dragon has no gills
- An axolotl has external gills
- A frog may have external gills briefly after hatching, but they get absorbed back into the body shortly thereafter
As a result, we cannot implement a hasGills()
function or hasGills
property on Animal
very easily… unless we use abstract classes or interfaces. Then, we can ask an Animal
if it has gills, but the actual implementation would be delegated to Frog
, Axolotl
, or KomodoDragon
.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.