Upload
yopeso
View
235
Download
1
Embed Size (px)
Citation preview
Andrei Raifura iOS Department Manager, YOPESO
#CodeWăy
Inheritance - The myth of code reuse
• How does Inheritance help us to reuse the code
• Why it doesn’t work
• The pitfalls of Inheritance
• To use or not to use
Agenda
• Encapsulation
• Abstraction
• Inheritance
• Polymorphism
OOP principlesI will teach you OOP
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)
Inheritance
‣ Two ears ‣ For legs ‣ Tail
Animal
Case study
Case study
CustomerYou
Case study
Can you program a Toyota Corolla for me?
CustomerYou
Case study
Mm..Sure!!
CustomerYou
Toyota Corolla
Wheels
Manufacturer
Transmission
4
Toyota
Front-wheel drive
Defining Car
class Car { let frontLeft = Wheel() let frontRight = Wheel() let rearLeft = Wheel() let rearRight = Wheel()
Defining Car
class Car { let frontLeft = Wheel() let frontRight = Wheel() let rearLeft = Wheel() let rearRight = Wheel() var manufacturer: String { get { return "Undefined" } }
Defining Car
class Car { . . .
func turnLeft(degrees: Double) { frontLeft.turnLeft(degrees) frontRight.turnLeft(degrees) } func turnRight(degrees: Double) { frontLeft.turnRight(degrees) frontRight.turnRight(degrees) }
Defining Car
class Car { . . .
func accelerate(kph: Double) { frontLeft.rotate(kph) frontRight.rotate(kph) } }
Defining Wheel
class Wheel { private var angle = 0.0 private var rotationSpeed = 0.0 func turnRight(degrees: Double) { angle += degrees } func turnLeft(degrees: Double) { angle -= degrees } func rotate(kph: Double) { rotationSpeed = kph } }
Defining Toyota Corolla
class ToyotaCorolla: Car { override var manufacturer: String { get { return "Toyota" } } }
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
Case study
Great! Now, i’d like to have a Toyota Corolla Sport
CustomerYou
Case study
Ok! will do!
CustomerYou
Toyota Corolla
Wheels
Manufacturer
Transmission
4
Toyota
Front-wheel drive
Toyota Corolla
Wheels
Manufacturer
Transmission
4
Toyota
Front-wheel drive
Toyota Corolla Sport
Wheels
Manufacturer
Transmission
4
Toyota
Rear-wheel drive
Defining Toyota Corolla Sport
class ToyotaCorollaSport: ToyotaCorolla { override func accelerate(kph: Double) { rearLeft.rotate(kph) rearRight.rotate(kph) } }
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
ToyotaCorollaSport
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
Case study
Woww! Now a Honda Civic and a Honda Civic
Sport
CustomerYou
Case study
Mmnn.. ok
CustomerYou
Honda Civic
Wheels
Manufacturer
Transmission
4
Front-wheel drive
Honda
Honda Civic Sport
Wheels
Manufacturer
Transmission
4
Rear-wheel drive
Honda
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
ToyotaCorollaSport
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
ToyotaCorollaSport
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
HondaCivic
HondaCivicSport
Defining Front-wheel Drive
class FrontWheelDriveCar: Car { override func accelerate(kph: Double) { frontLeft.rotate(kph) frontRight.rotate(kph) } }
Defining Rear-wheel Drive
class RearWheelDriveCar: Car { override func accelerate(kph: Double) { rearLeft.rotate(kph) rearRight.rotate(kph) } }
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
ToyotaCorollaSport
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
HondaCivic
HondaCivicSport
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar
ToyotaCorollaSport
RearWheelDriveCar
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
HondaCivic HondaCivicSport
Refactoring Toyota Corolla
class ToyotaCorolla: FrontWheelDriveCar { override var manufacturer: String { get { return "Toyota" } } }
Refactoring Toyota Corolla Sport
class ToyotaCorollaSport: RearWheelDriveCar { override var manufacturer: String { get { return "Toyota" } } }
Defining Honda Civic
class HondaCivic: FrontWheelDriveCar { override var manufacturer: String { get { return "Honda" } } }
Defining Honda Civic Sport
class HondaCivicSport: RearWheelDriveCar { override var manufacturer: String { get { return "Honda" } } }
Lexus GX
Wheels
Manufacturer
Transmission
4
All-wheel drive
Lexus
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar
ToyotaCorollaSport
RearWheelDriveCar
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
HondaCivic HondaCivicSport
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar
ToyotaCorollaSport
RearWheelDriveCar
ToyotaCorolla
- turnLeft - turnRight - rotate
Wheel
HondaCivic HondaCivicSport
AllWheelDriveCar
LexusGX
Defining All-wheel Drive
class AllWheelDriveCar: Car { override func accelerate(kph: Double) { frontLeft.rotate(kph) frontRight.rotate(kph) rearLeft.rotate(kph) rearRight.rotate(kph) } }
Defining Lexus GX
class LexusGX: AllWheelDriveCar { override var manufacturer: String { get { return "Lexus" } } }
Case study
Amazing! But, can you make
me an experimental car?
CustomerYou
Case study
It will switch between two-wheel drive and all-wheel
drive…
CustomerYou
Case study
And will turn with all four wheels.
CustomerYou
Experimental
Wheels
Manufacturer
Transmission
4
Front-wheel drive
Experimental
Experimental
Wheels
Manufacturer
Transmission
4
Front-wheel drive & All-wheel drive
Experimental
Experimental
Wheels
Manufacturer
Transmission
4
Front-wheel drive & All-wheel drive
Experimental
Steering All-wheel steering
Are you Seriously?
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar RearWheelDriveCar
- turnLeft - turnRight - rotate
Wheel
AllWheelDriveCar
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar RearWheelDriveCar
- turnLeft - turnRight - rotate
Wheel
AllWheelDriveCar
ExperimentalCar
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar RearWheelDriveCar
- turnLeft - turnRight - rotate
Wheel
AllWheelDriveCar
ExperimentalCar
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar RearWheelDriveCar
- turnLeft - turnRight - rotate
Wheel
AllWheelDriveCar
ExperimentalCar
Class Diagram
- manufacturer - turnLeft - turnRight - accelerate
Car
FrontWheelDriveCar RearWheelDriveCar
- turnLeft - turnRight - rotate
Wheel
AllWheelDriveCar
ExperimentalCar
The Diamond of Dread
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)
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)
Solutions
Demo
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
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
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
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
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
Liskov Substitution Principle
Subtypes must be substitutable for their base types.
Robert C. Martin (Uncle Bob)
Violation of LSP
class File { var path: String! var data: NSData! func loadData() { // Retrieve data from disk } func saveData() { // Write data to disk } }
class ReadOnlyFile: File { override func saveData() { print("Cannot write data") } }
Violation of LSP
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
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
Should we avoid inheritance altogether?
To use?
Use Inheritance when your derived class truly is the type you're extending.And it will always be!
The Employee
- firstName - lastName - age - department
Employee
The Employee and the Student
- firstName - lastName - age - year - faculty
Student
- firstName - lastName - age - department
Employee
The Employee and the Student
- firstName - lastName - age
Person
- department
Employee
- year - faculty
Student
The Employee and the Student
- firstName - lastName - age
Person
- department
Employee
- year - faculty
Student
I am a Student. And an Employee.
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.
The Employee and the Student
- firstName - lastName - age
Person
Occupation
- department
Employee- year - faculty
Student Unemployed
Or not to use?
How about polymorphism?
Consider using Protocols* to achieve a polymorphic behaviour.* Also known as Interfaces in other languages
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?
• 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
Use Inheritance Wisely!
Questions?
Contacts
Raifura Andrei iOS Department Manager, YOPESO
#CodeWăy