Skip to content

Instantly share code, notes, and snippets.

@NSExceptional
Created April 4, 2019 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NSExceptional/9fad2ecfb91a7221331129c47137205e to your computer and use it in GitHub Desktop.
Save NSExceptional/9fad2ecfb91a7221331129c47137205e to your computer and use it in GitHub Desktop.
A demonstration of a use case where inheritance is preferred to composition.
protocol Mammal {
var age: Int { get set }
var offspring: Int { get set }
func grow()
func reproduce() -> Self
}
protocol Person: Mammal {
var name: String { get }
// ...
init(named name: String)
func growOld()
func speak()
}
extension Person {
func speak() {
print("My name is \(name) and I'm \(age) year(s) old")
}
func growOld() {
for _ in 0..<50 { self.grow() }
}
}
class Employee: Person {
enum Job {
case programmer
case businessOwner
case stayAtHomeParent
}
var offspring: Int = 0
var age: Int = 1
var name: String
var occupation: Job? = nil
required init(named name: String) {
self.name = name
}
convenience init(named name: String, job: Job) {
self.init(named: name)
self.occupation = job
}
func grow() {
self.age += 1
if self.age.isMultiple(of: 10) {
self.speak()
}
}
func reproduce() -> Self {
self.offspring += 1
return type(of: self).init(named: self.name + " Jr.")
}
}
let e = Employee(named: "Steve", job: .businessOwner)
e.growOld()
class Mammal {
var age: Int = 1
var offspring: Int = 0
func grow() {
self.age += 1
}
func reproduce() -> Self {
fatalError("Subclasses must override")
}
}
class Person: Mammal {
let name: String
// ...
required init(named name: String) {
self.name = name
}
func speak() {
print("My name is \(name) and I'm \(age) year(s) old")
}
override func grow() {
super.grow()
if self.age.isMultiple(of: 10) {
self.speak()
}
}
func growOld() {
for _ in 0..<50 { self.grow() }
}
override func reproduce() -> Self {
self.offspring += 1
return type(of: self).init(named: self.name + " Jr.")
}
}
class Employee: Person {
enum Job {
case programmer
case businessOwner
case stayAtHomeParent
}
var occupation: Job? = nil
convenience init(named name: String, job: Job) {
self.init(named: name)
self.occupation = job
}
}
let e = Employee(named: "Steve", job: .businessOwner)
e.growOld()
// Prints:
// My name is Steve and I'm 10 year(s) old
// My name is Steve and I'm 20 year(s) old
// My name is Steve and I'm 30 year(s) old
// My name is Steve and I'm 40 year(s) old
// My name is Steve and I'm 50 year(s) old
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment