Subclass and Inheritance
In this chapter, we will be discussing the features of subclassing and inheritance. This is an important features that other data types such as structures do not have. After we defined structures, we can create instances of structures to be used as variables or constant. If we are to make changes, we have to change the definition of the original structure or we have to define a different structure with a different name. However, if we use class and objects, we can reuse the code or modify the class without changing the main class. We can create subclass from the base class and make amendment or modification. This feature encourage re-use of the code and we can share the code to other programmer.
Before we start to perform subclass, lets define a base class using the example in the previous post.
class TransportVehicle {
// Properties var speed:Double var maximumLoad:Double var numberOfPassenger:Int // Internal Used Properties var totalUseage: Int var preference: Int let maximumUsed = 50 init() { self.speed = 1.0 self.maximumLoad = 10.0 self.numberOfPassenger = 1 self.totalUseage = 0 self.preference = 0 } init(speed: Double, maximumLoad: Double, numberOfPassenger: Int) { self.speed = speed self.maximumLoad = maximumLoad self.numberOfPassenger = numberOfPassenger // User need to enter value but we still need to initialized them self.totalUseage = 0 self.preference = 0 } // Methods func displayInternalUsedNumber() { print("The internal used number is \(self.maximumUsed).") } func description () -> String { return "This is the base class" } } |
Next, we will define the sub class in the next section.
Define Subclass
To define subclass, we use the keyword class together with the name of base class. Base class is the class that do not base on other class. The syntax is as follows:
class <subclass_name>:<baseclass_name> {
}
We can define a subclass as follows:
class LandTransportVehicle: TransportVehicle {
} |
To implement the subclass, we create an instance as follow:
let landTransportVehicle1 = LandTransportVehicle()
|
We can use landTransportVehicle1 as the base class as shown below:
let landTransportVehicle1 = LandTransportVehicle()
landTransportVehicle1.maximumLoad landTransportVehicle1.numberOfPassenger landTransportVehicle1.speed landTransportVehicle1.speed = 100.0 landTransportVehicle1.speed landTransportVehicle1.displayInternalUsedNumber() let descriptionString = landTransportVehicle1.description() |
We can create an instance based on the subclass. The subclass inherits all the variables and function from the base class. The subclass can be empty and the instance still able to perform methods or access properties that is in the base class.
However, it is useless if we define a subclass without any modification. The purpose of subclassing is to add features and make modification that are specific to the subclass. Lets modify the subclass.
class LandTransportVehicle: TransportVehicle {
// Property let modeOfTransport = "Land" let modeOfTransportCode = 1 } |
The implementation is as follows:
let landTranportpVehicle2 = LandTransportVehicle()
landTranportpVehicle2.maximumLoad landTranportpVehicle2.numberOfPassenger landTranportpVehicle2.speed landTranportpVehicle2.modeOfTransport |
We have added 2 constant. These constant identify the instances as land transport vehicle.
Initialization
Using our previous example, we can dispense with initializer because the added constant is being initialized during definition. If we were to add some variable and we want programmer to input these variable, we can use an initializer.
Please checkout the subclass definition below:
class LandTransportVehicle: TransportVehicle {
// Property let modeOfTransport = "Land" let modeOfTransportCode = 1 var isThisTrain: Bool var poweredBy: String override init() { self.isThisTrain = false self.poweredBy = "Gas" super.init() } init(speed: Double, maximumLoad: Double, numberOfPassenger: Int, isThisTrain: Bool, poweredBy: String) { self.isThisTrain = isThisTrain self.poweredBy = poweredBy super.init() self.speed = speed self.maximumLoad = maximumLoad self.numberOfPassenger = numberOfPassenger } } |
As shown above, we have added 2 more variables; a boolean and a string. Since we did not initialized these 2 variables, we need to add the default initializer init().
Since we have init() in the parent class, we need to override them using the override keyword. Next we need to set the default for the newly added variable. After that we need to call the init() from the parent class by using the super keyword. Super refers to the parent class.
For init(speed: Double, maximumLoad: Double, numberOfPassenger: Int, isThisTrain: Bool, poweredBy: String), override keyword is not necessary because it has five input, whereas init(speed: Double, maximumLoad: Double, numberOfPassenger: Int) only has 3 variables. As far as the system is concern, they are considered different initializer.
Override Method
Besides initializer, we can also override the methods. We cannot override properties by changing the values. We change the value using initializer or we can set the value directly.
To override function, we use the keyword override just before the function name. See example below:
override func description() -> String {
return "This is a subclass that is based on transport vehicle base class. This class return "
}
|
Implementation is as below:
let landTransportVehicle3 = LandTransportVehicle()
landTransportVehicle3.maximumLoad let myString = landTransportVehicle3.description() |
This is a very powerful feature as we can change the behavior of the function from the base class.
We can further create another subclass under land transport. In the follow example, we are creating 2 subclass, they are cars and bus.
class Cars: LandTransportVehicle {
// properties
var numberOfDoors = Int()
var numberOfWheels = Int()
override init() {
self.numberOfDoors = 2
self.numberOfWheels = 4
super.init()
}
override func description() -> String {
return "This is subclass cars parent is land transport vehicle > transport vehicle."
}
}
class Bus: LandTransportVehicle {
// Properties
var numberOfDoors = Int()
var numberOfWheels = Int()
override init() {
self.numberOfDoors = 2
self.numberOfWheels = 6
super.init()
}
override func description() -> String {
return "This is subclass bus. Parent is land transport vehicle > transport vehicle."
}
}
|
The implementation is as follows:
let car1 = Cars()
let car2 = Cars() let bus1 = Bus() let bus2 = Bus() let carDesc1 = car1.description() car1.numberOfWheels car2.displayInternalUsedNumber() car2.speed = 130 bus1.speed = 90 bus1.numberOfPassenger = 30 bus2.speed = 90 bus2.numberOfPassenger = 40 |
As we can see from the example above, additional properties and methods stack up down the class hierarchy. This save us time and preventing us from rewriting code that are similar. We can also delegate different team to work on different subclass.
****
No comments:
Post a Comment