In this chapter, you will learn about one of the most important topics of object-oriented programming: inheritance. We will work with examples on how to create class hierarchies, override methods, overload methods, work with inherited initializers, and overload operators. In addition, you will learn about polymorphism and basic typecasting.
So far, we have created classes to generate blueprints for real-life objects. Now, it is time to take advantage of the more advanced features of object-oriented programming and start designing a hierarchy of classes instead of working with isolated classes. First, we will design all the classes that we need based on the requirements, and then, we will use the features available in Swift to code the design.
We worked with classes to represent superheroes. Now, let's imagine that we have to develop a very complex app that requires us to work with hundreds of types of domestic animals. We already know that the app will start working with the following four domestic animal species:
The previous list provides the scientific names for each domestic animal species. Of course, we will work with the most common name for each species and just have the scientific name as a type property. Thus, we won't have a complex class name, such as CanisLupusFamiliaris
, but we will use Dog
instead.
Initially, we'll have to work with a limited number of breeds for the previously enumerated four domestic animal species. Additionally, in the future, it will be necessary to work with other members of the listed domestic animal species, other domestic mammals, and even reptiles and birds that don't belong to the domestic animal species. Thus, our object-oriented design must be ready to be expanded for future requirements. In fact, you will understand how object-oriented programming makes it easy to expand an existing design for future requirements.
Of course, we don't want our object-oriented design to model a complete representation of the animal kingdom and its classification. We just want to create the necessary classes to have a flexible model that can be easily expanded. The animal kingdom is extremely complex, and we will keep our focus in just a few members of this huge family.
In this case, we will need many classes to represent a complex classification of animals and their breeds. The following list enumerates the classes that we will create and their descriptions:
Animal
: This is a class that generalizes all the members of the animal kingdom. Dogs, guinea pigs, domestic canaries, cats, reptiles, and birds have one thing in common: they are animals. Thus, it makes sense to create a class that will be the baseline for the different classes of animals that we may have to represent in our object-oriented design.Mammal
: This is a class that generalizes all the mammalian animals. Mammals are different from reptiles, amphibians, birds, and insects. As we already know that we will also have to model reptiles and birds, we will create a Mammal
class at this level.Bird
: This is a class that generalizes all birds. Birds are different from mammals, reptiles, amphibians, and insects. We already know that we will also have to model reptiles and birds. In fact, a domestic canary is a bird, so we will create a Bird
class at the same level as Mammal
.DomesticMammal
: This is a subclass of Mammal
. The tiger (Panthera tigris) is the largest and heaviest living species of the cat family. A tiger is a cat, but it is completely different from a domestic cat. The initial requirements tell us that we will work with both domestic and wild animals, so we will create a class that generalizes all domestic mammal animals. In the future, we will have a WildMammal
subclass that will generalize all the wild mammalian animals.DomesticBird
: The ostrich (Struthio camelus) is the largest living bird. However, obviously, an ostrich is completely different from a domestic canary. As we will work with both domestic and wild birds, we will create a class that generalizes all domestic birds. In the future, we will have a WildBird
class that will generalize all wild birds.Dog
: We could go on specializing the DomesticMammal
class with additional subclasses until we reach a Dog
class. For example, we might create a CanisCarnivorianDomesticMammal
subclass and then make the Dog
class inherit from it. However, the kind of app we have to develop doesn't require any intermediary class between DomesticMammal
and Dog
. At this level, we will also have a Cat
class. The Dog
class generalizes the properties and methods required for a dog in our application. Subclasses of the Dog
class will represent the different families of the dog breed. For example, one of the main differences between a dog and a cat in our application domain is that a dog barks and a cat meows.Cat
: The Cat
class generalizes the properties and methods required for a cat in our application. Subclasses of the Cat
class will represent the different families of the cat breed. In this case, we create a class to represent domestic cats, so Cat
is a subclass of DomesticMammal
.GuineaPig
: The GuineaPig
class generalizes all the properties and methods required for a guinea pig in our application.TerrierDog
: Each dog breed belongs to a family. We will work with a huge amount of dog breeds, and some profile values determined by their family are very important for our application. Thus, we will create a subclass of Dog
for each family. In this case, the sample TerrierDog
class represents the Terrier family.SmoothFoxTerrier
: Finally, a subclass of a dog breed family class will represent a specific dog breed that belongs to the family. Its breed determines the dog's looks and behavior. A dog that belongs to the Smooth Fox Terrier breed is completely different from a dog that belongs to the Tibetan Spaniel breed. Thus, we will create instances of the classes at this level to give life to each dog in our application. In this case, the SmoothFoxTerrier
class models an animal, a mammal, domestic mammal, dog, and terrier family dog, specifically, a dog that belongs to the Smooth Fox Terrier breed.DomesticCanary
: The DomesticCanary
class generalizes the properties and methods required for a domestic canary in our application.Each class listed in the previous list represents a specialization of the previous class--that is, its superclass, parent class, or superset--as shown in the following table:
Superclass, parent class, or superset |
Subclass, child class, or subset |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Our application requires many members of the Terrier family, so the SmoothFoxTerrier
class will not be the only subclass of TerrierDog
. In the future, we will have the following three additional subclasses of TerrierDog
:
AiredaleTerrier
: This is the Airedale Terrier breedBullTerrier
: This is the Bull Terrier breedCairnTerrier
: This is the Cairn Terrier breedThe following UML diagram shows the previous classes organized in a class hierarchy:
18.216.27.251