Reader small image

You're reading from  Object???Oriented Programming with Swift 2

Product typeBook
Published inJan 2016
Reading LevelIntermediate
Publisher
ISBN-139781785885693
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Gaston C. Hillar
Gaston C. Hillar
author image
Gaston C. Hillar

Gaston C. Hillar is Italian and has been working with computers since he was 8 years old. Gaston has a Bachelor's degree in computer science (graduated with honors) and an MBA. Currently, Gaston is an independent IT consultant and a freelance author who is always looking for new adventures anywhere in the world. He was a senior contributing editor at Dr. Dobb's, and has written more than a hundred articles on software development topics. He has received the prestigious Intel Black Belt Software Developer award eight times. He has written many articles about Java for Oracle Java Magazine. Gaston was also a former Microsoft MVP in technical computing. He lives with his wife, Vanesa, and his two sons, Kevin and Brandon.
Read more about Gaston C. Hillar

Right arrow

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 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 name for each domestic animal species. Of course, we will work with the most common name for...

Understanding inheritance


When a class inherits from another class, it inherits all the elements that compose the parent class, which is also known as a superclass. The class that inherits the elements is known as a subclass. For example, the Mammal subclass inherits all the properties, instance fields or instance attributes, and class fields or class attributes defined in the Animal superclass.

The Animal abstract class is the baseline for our class hierarchy. We say that it is an abstract class because we shouldn't create instances of the Animal class; instead, we must create instances of the specific subclasses of Animal. However, we must take into account that Swift doesn't allow us to declare a class as an abstract class.

We require each Animal to specify its age, so we will have to specify the age when we create any Animal—that is, any instance of any Animal subclass. The class will define an age property and display a message whenever an animal is created. The class defines three type...

Declaring classes that inherit from another class


The following lines show the code for the Animal base class in Swift. The class header doesn't specify a base class, so this class will become our base class for the other classes:

public class Animal {
    public static var numberOfLegs: Int {
        get {
            return 0;

        }
    }
    public static var averageNumberOfChildren: Int {
        get {
            return 0;
        }
    }
    
    public static var abilityToFly: Bool {
        get {
            return false;
        }
    }
    
    public var age: Int
    
    init(age : Int) {
        self.age = age
        print("Animal created")
    }

    public static func printALeg() {
        preconditionFailure("The pringALeg method must be overriden")
    }
    
    public func printLegs() {
        for _ in 0..<self.dynamicType.numberOfLegs {
            self.dynamicType.printALeg()
        }
        print(String())

    }
    
    public static func printAChild()...

Overriding and overloading methods


Swift allows us to define a method with the same name many times with different arguments. This feature is known as method overloading. In some cases, as in our previous example, we can overload the initializer. However, it is very important to mention that a similar effect might be achieved with optional parameters or default values for specific arguments.

For example, we can take advantage of method overloading to define multiple versions of the bark method that we have to define in the Dog class. However, it is very important to avoid code duplication when we overload methods.

Sometimes, we define a method in a class, and we know that a subclass might need to provide a different version of the method. When a subclass provides a different implementation of a method defined in a superclass with the same name, arguments, and return type, we say that we are overriding a method. When we override a method, the implementation in the subclass overwrites the code...

Overriding properties


First, we will try to override the numberOfLegs type property that the Dog class will inherit from the Animal base class. We will face an issue and solve it. The following lines show the code for a simplified version of the Dog class that inherits from DomesticMammal and just tries to override the numberOfLegs type property:

public class Dog: DomesticMammal {
    public static override var numberOfLegs: Int {
        get {
            return 4;
        }
    }
}

After we enter the previous lines in the Playground, we will see the following error message in the line that tries to override the numberOfLegs type property: error: class var overrides a 'final' class var. The following screenshot shows the error in the Playground:

Tip

When we declare either a type property or method with the static keyword in a base class, it isn't possible to override it in a subclass. Thus, if we want to enable either a type property or method to be overridden in the subclasses, it is necessary...

Controlling whether subclasses can or cannot override members


The following lines show the code for the complete Dog class that inherits from DomesticMammal. Note that the following code replaces the previous Dog class that just declared an overridden type property:

public class Dog: DomesticMammal {
    public static override var numberOfLegs: Int {
        get {
            return 4;
        }
    }
    
    public static override var abilityToFly: Bool {
        get {
            return false;
        }
    }
    
    public var breed: String {

        get {
            return "Just a dog"
        }
    }
    
    public var breedFamily: String {

        get {
            return "Dog"
        }
    }
    
    private func initializeDog() {
        print("Dog created")
    }
    
    public override init(age: Int, name: String, favoriteToy: String) {
        super.init(age: age, name: name, favoriteToy: favoriteToy)
        initializeDog()
    }
    
    public override init(age: Int...

Working with typecasting and polymorphism


We can use the same method—that is, the same name and arguments—to cause different things to happen according to the class on which we invoke the method. In object-oriented programming, this feature is known as polymorphism.

For example, consider that we defined a talk method in the Animal class. The different subclasses of Animal must override this method to provide their own implementation of talk.

The Dog class overrode this method to print the representation of a dog barking—that is, a Woof message. On the other hand, a Cat class will override this method to print the representation of a cat meowing—that is, a Meow message.

Now, let's think about a CartoonDog class that represents a dog that can really talk as part of a cartoon. The CartoonDog class would override the talk method to print a Hello message because the dog can really talk.

Thus, depending on the type of the instance, we will see a different result after invoking the same method with...

Taking advantage of operator overloading


Swift allows us to redefine specific operators to work in a different way based on the classes to which we apply them. For example, we can make comparison operators, such as less than (<) and greater than (>), return the results of comparing the age value when they are applied to instances of Dog.

Tip

The redefinition of operators to work in a specific way when applied to instances of specific classes is known as operator overloading. Swift allows us to overload operators through the usage of operator functions.

An operator that works in one way when applied to an instance of a class might work differently on instances of another class. We can also redefine the overloaded operators to work on specific subclasses. For example, we can make the comparison operators work in a different way in a superclass and its subclass.

We want to be able to compare the age of the different Animal instances using the following binary operators in Swift:

  • Less than...

Declaring operator functions for specific subclasses


We already declared an operator function that allows any instance of Animal or its subclasses to use the postfix increment (++) operator. However, sometimes we want to specify a different behavior for one of the subclasses and its subclasses.

For example, we might want to express the age of dogs in the age value that is equivalent to humans. We can declare an operator function for the postfix increment (++) operator that receives a Dog instance as an argument and increments the age value 7 years instead of just one. The following lines show the code that achieves this goal:

public postfix func ++ (dog: Dog) {
    dog.age += 7
}

The following lines create an instance of the SmoothFoxTerrier class named goofy, print the age for goofy, apply the postfix ++ operator, and print the new age. Because SmoothFoxTerrier is a subclass of Dog, Swift invokes the operator function that receives a Dog instance instead of invoking the one that receives an...

Exercises


Create operator functions to allow us to determine whether two DomesticMammal instances are equal or not with the == and != operators. We will consider the instances to be equal when their age, name, and favoriteToy properties have the same value.

Create the following three new subclasses of the TerrierDog class:

  • AiredaleTerrier: This is an Airedale Terrier breed

  • BullTerrier: This is a Bull Terrier breed

  • CairnTerrier: This is a Cairn Terrier breed

Add the necessary code to these classes to print text that represents the children in a different way than we did for the SmoothFoxTerrier class. Test the results by creating an instance of each of these classes and calling the printChildren method.

Test your knowledge


  1. When you use the static var keywords to declare a type property:

    1. You cannot override the type property in the subclasses.

    2. You can override the type property in the subclasses.

    3. You can override the type property only in the superclass.

  2. When you use the class var keywords to declare a type property:

    1. You cannot override the type property in the subclasses.

    2. You can override the type property in the subclasses.

    3. You can override the type property only in the superclass.

  3. When you use the final keyword to declare an instance method:

    1. You cannot override the instance method in the subclasses.

    2. You can override the instance method in the subclasses.

    3. You can override the instance method only once—that is, in just one subclass.

  4. Polymorphism means:

    1. We can call the same method—that is, the same name and arguments—in instances of classes that aren't included in the same hierarchy tree.

    2. We can use the same method—that is, the same name and arguments—to cause different things to happen according to the...

Summary


In this chapter, you learned how to take advantage of simple inheritance to specialize a base class. We designed many classes from top to bottom using chained initializers, type properties, computed properties, stored properties, and methods. Then, we coded most of these classes in the interactive Playground, taking advantage of different mechanisms provided by Swift.

We took advantage of operator functions to overload operators that we could use with the instances of our classes. We overrode and overloaded initializers, type properties, and methods. We took advantage of one of the most exciting object-oriented features: polymorphism.

Now that we have learned to work with inheritance, abstraction, and specialization, we are ready to work with protocols, which is the topic of the next chapter.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Object???Oriented Programming with Swift 2
Published in: Jan 2016Publisher: ISBN-13: 9781785885693
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Gaston C. Hillar

Gaston C. Hillar is Italian and has been working with computers since he was 8 years old. Gaston has a Bachelor's degree in computer science (graduated with honors) and an MBA. Currently, Gaston is an independent IT consultant and a freelance author who is always looking for new adventures anywhere in the world. He was a senior contributing editor at Dr. Dobb's, and has written more than a hundred articles on software development topics. He has received the prestigious Intel Black Belt Software Developer award eight times. He has written many articles about Java for Oracle Java Magazine. Gaston was also a former Microsoft MVP in technical computing. He lives with his wife, Vanesa, and his two sons, Kevin and Brandon.
Read more about Gaston C. Hillar