Chapter 4. Inheritance, Abstraction, and Specialization

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.

Creating class hierarchies to abstract and specialize behavior

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:

  • Dog (Canis lupus familiaris)
  • Guinea pig (Cavia porcellus)
  • Domestic canary (Serinus canaria domestica)
  • Cat (Felis silvestris catus)

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.

Tip

The examples will also allow you to understand that object-oriented programming doesn't sacrifice flexibility. We can start with a simple class hierarchy that can be expanded as the application's complexity increases and we have more information about new requirements.

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

Animal

Mammal

Animal

Bird

Mammal

DomesticMammal

Bird

DomesticBird

DomesticMammal

Dog

DomesticMammal

Cat

DomesticMammal

GuineaPig

DomesticBird

DomesticCanary

Dog

TerrierDog

TerrierDog

SmoothFoxTerrier

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 breed
  • BullTerrier: This is the Bull Terrier breed
  • CairnTerrier: This is the Cairn Terrier breed

The following UML diagram shows the previous classes organized in a class hierarchy:

Creating class hierarchies to abstract and specialize behavior

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.89.82