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 designated 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 the 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 provided in the superclass.

Tip

It is also possible to override methods related to properties, such as getters and setters, and the other members of a class in the subclasses.

The following lines show the code for the DomesticMammal class that inherits from Mammal. Note the class keyword followed by the class name DomesticMammal, a colon (:), and Mammal, which is the superclass from which it inherits, in the class definition. The code file for the sample is included in the swift_3_oop_chapter_04_04 folder:

    open class DomesticMammal: Mammal { 
      open var name = String() 
      open var favoriteToy = String() 
     
      private func initialize(name: String, favoriteToy: String) { 
        self.name = name 
        self.favoriteToy = favoriteToy 
        print("DomesticMammal created") 
      } 
     
      init(age: Int, name: String, favoriteToy: String) { 
        super.init(age: age) 
        initialize(name: name, favoriteToy: favoriteToy) 
      } 
     
      init(age: Int, isPregnant: Bool, name: String, favoriteToy: 
      String) { 
        super.init(age: age, isPregnant: isPregnant) 
        initialize(name: name, favoriteToy: favoriteToy) 
      } 
     
      open func talk() { 
        print("(name): talks") 
      } 
    } 

The preceding class declares two designated initializers. One of them requires age, name, and favoriteToy to create an instance of a class. The other initializer adds an isPregnant argument. As it happened in the Mammal class, the code within each initializer uses super.init to call the appropriate superclass' initializer. In one case, we just need the age value received as an argument, and in the other case, it is also necessary to add the isPregnant value. Once the superclass's initializer finishes its execution, the initializers call the initialize private method that initializes the name and favoriteToy properties. After the method finishes initializing the properties, it prints a message indicating that a DomesticMammal class is created. The following lines show both initializer declarations:

    init(age: Int, name: String, favoriteToy: String) { 
    init(age: Int, isPregnant: Bool, name: String, favoriteToy: String) 
    { 

The class defines two stored properties: name and favoriteToy. The talk instance method displays a message with the name value followed by a colon (:) and talks. Note that we will be able to override this method in any subclass of DomesticMammal because each domestic mammal has a different way of talking.

The following lines create an instance of the DomesticMammal class in the Playground using the initializer that requires three arguments: age, name, and favoriteToy. The code file for the sample is included in the swift_3_oop_chapter_04_04 folder:

    var scooby = DomesticMammal(age: 5, name: "Scooby", favoriteToy: 
    "Scarf") 
    scooby.printAge() 
    scooby.talk() 
    print(scooby.favoriteToy) 
    print(scooby.isPregnant) 

The following lines show the results of the preceding lines. We can detect the chained execution of the initializers in the base class (Animal), the superclass (Mammal), and the class (DomesticMammal). The first line displays Animal created, the second line displays Mammal created, and the third line displays Domestic Mammal created. The call to the printAge method defined in the base class (Animal) prints the actual value of the age property in this instance of the DomesticMammal class. The call to the talk method displays the message that starts with the name value. A line prints the value of the favoriteToy property that is defined in this class, and then, another line prints the value of the inherited isPregnant property. In this case, the value of the isPregnant property was initialized with false because we didn't specify a value for it:

    Animal created 
    Mammal created 
    DomesticMammal created 
    I am 5 years old. 
    Scooby: talks 
    Scarf 
    false 

The following lines create another instance of the DomesticMammal class in the Playground using the initializer that requires four arguments: age, isPregnant, name, and favoriteToy:

    var lady = DomesticMammal(age: 6, isPregnant: true, name: "Lady", 
    favoriteToy: "Teddy") 
    lady.printAge() 
    lady.talk() 
    print(lady.favoriteToy) 
    print(lady.isPregnant) 

The following lines show the results of the preceding lines. The last line prints the value of the isPregnant property that was initialized with true in the initializer defined in the Mammal class and called through the initializers' chain:

    Animal created 
    Mammal created 
    DomesticMammal created 
    I am 6 years old. 
    Lady: talks 
    Teddy 
    true 

The following screenshot shows the results of executing the preceding code in the Playground:

Overriding and overloading methods

Dogs are domestic mammals that have four legs, and so far, nobody has discovered a dog breed with the ability to fly. When we define the Dog class that inherits from DomesticMammal, we will want to override the numberOfLegs type property to make its getter return 4 and make sure that the abilityToFly type property will always return false in Dog and any of its subclasses.

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

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