Watch this presentation if you want to know why inheritance is not always the most appropriate method for code reuse - and what to do instead.
Watch the video here:
https://www.youtube.com/watch?v=H6m0W-eDyAk
The code used for the demo:
https://github.com/yopeso/Inheritance
4. Inheritance
“…It is a mechanism for code reuse and to allow independent
extensions of the original software via public classes and interfaces…”
Wikipedia, Inheritance (object-oriented programming)
11. Defining Car
class Car {
let frontLeft = Wheel()
let frontRight = Wheel()
let rearLeft = Wheel()
let rearRight = Wheel()
12. Defining Car
class Car {
let frontLeft = Wheel()
let frontRight = Wheel()
let rearLeft = Wheel()
let rearRight = Wheel()
var manufacturer: String {
get { return "Undefined" }
}
13. Defining Car
class Car {
. . .
func turnLeft(degrees: Double) {
frontLeft.turnLeft(degrees)
frontRight.turnLeft(degrees)
}
func turnRight(degrees: Double) {
frontLeft.turnRight(degrees)
frontRight.turnRight(degrees)
}
14. Defining Car
class Car {
. . .
func accelerate(kph: Double) {
frontLeft.rotate(kph)
frontRight.rotate(kph)
}
}
56. Class Diagram
- manufacturer
- turnLeft
- turnRight
- accelerate
Car
FrontWheelDriveCar RearWheelDriveCar
- turnLeft
- turnRight
- rotate
Wheel
AllWheelDriveCar
ExperimentalCar
The Diamond of Dread
57. Code reuse
“…It is a mechanism for code reuse and to allow independent
extensions of the original software via public classes and interfaces…”
Wikipedia, Inheritance (object-oriented programming)
58. Code reuse
“…It is a mechanism for code reuse and to allow independent
extensions of the original software via public classes and interfaces…”
Wikipedia, Inheritance (object-oriented programming)
61. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Makes the code fragile
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
62. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Makes the code fragile
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
63. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
• Makes the code fragile
64. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
• Makes the code fragile
65. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
• Makes the code fragile
67. Violation of LSP
class File {
var path: String!
var data: NSData!
func loadData() {
// Retrieve data from disk
}
func saveData() {
// Write data to disk
}
}
68. class ReadOnlyFile: File {
override func saveData() {
print("Cannot write data")
}
}
Violation of LSP
69. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
• Makes the code fragile
70. Inheritance pitfalls
• A very tight binding between a superclass and its subclasses
• Makes the code fragile
• Difficult to debug
• Inheritance relationships generally can't be altered at runtime.
• Leads to violation of Liskov Substitution Principle
• Difficult to test
74. The Employee and the Student
- firstName
- lastName
- age
- year
- faculty
Student
- firstName
- lastName
- age
- department
Employee
75. The Employee and the Student
- firstName
- lastName
- age
Person
- department
Employee
- year
- faculty
Student
76. The Employee and the Student
- firstName
- lastName
- age
Person
- department
Employee
- year
- faculty
Student
I am a Student.
And an Employee.
77. The Employee and the Student
- firstName
- lastName
- age
Person
- department
Employee
- year
- faculty
Student
I am a Student.
And an Employee.
I've just become
unemployed.
78. The Employee and the Student
- firstName
- lastName
- age
Person
Occupation
- department
Employee
- year
- faculty
Student Unemployed
79. Or not to use?
How about polymorphism?
Consider using Protocols* to achieve a polymorphic behaviour.
* Also known as Interfaces in other languages
80. I need to reuse some code from superclass. No
The derived class is almost the extending type No
The derived class is the extending type but might change in
the future No
I need a polymorphic behaviour No
The derived class truly is the extending type. And it won't
change.
I swear!
Yes
To use or Not to use?
81. • How does Inheritance help us to reuse the code
• Why it doesn’t work
• The pitfalls of Inheritance
• To use or not to use
Review