Polymorphism
Part of the Object Oriented Programming section of Coddy's Swift journey. Lesson 32 of 57.
Polymorphism means one piece of code works with values of many types, and each value responds in its own way. The loop below calls sound() without knowing which animal it holds:
class Animal {
func sound() -> String { "..." }
}
class Dog: Animal {
override func sound() -> String { "Woof" }
}
class Cow: Animal {
override func sound() -> String { "Moo" }
}
let farm: [Animal] = [Dog(), Cow(), Dog()]
for a in farm { print(a.sound()) }Output:
Woof
Moo
WoofSwift decides which implementation to run at run time, from the actual object. The variable's declared type does not matter; the object's type does:
class Animal {
func sound() -> String { "..." }
}
class Cat: Animal {
override func sound() -> String { "Meow" }
}
let pet: Animal = Cat()
print(pet.sound())Output:
MeowProtocols give the same flexibility to structs and enums. Here one function prints any list of Drawable values:
protocol Drawable {
func draw() -> String
}
struct Line: Drawable {
let length: Int
func draw() -> String { String(repeating: "-", count: length) }
}
struct Box: Drawable {
func draw() -> String { "[ ]" }
}
func render(_ items: [any Drawable]) -> String {
items.map { $0.draw() }.joined(separator: " ")
}
print(render([Line(length: 3), Box(), Line(length: 1)]))Output:
--- [ ] -Polymorphism replaces long if/switch chains over kinds of things. Instead of asking what a value is and then deciding what to do, you ask the value to do it. Adding a new kind means adding a new type, not editing every switch:
// without polymorphism
if kind == "dog" { print("Woof") } else if kind == "cow" { print("Moo") }
// with polymorphism
for animal in farm { print(animal.sound()) }Challenge
EasyAnimal has name, legs() (4) and describe(), which returns Rex has 4 legs and says Woof, built from legs() and sound(). Declare Dog (sound Woof), Bird (2 legs, sound Tweet) and Snake (0 legs, sound Hiss) by overriding only legs() and sound().
The supplied code reads lines dog,Rex, bird,Pip or snake,Kaa, stores the animals in one [Animal] array and prints describe() for each.
Your code goes in Animal.swift, Dog.swift, Bird.swift and Snake.swift. main.swift holds the supplied input/output code and cannot be edited.
Try it yourself
// Supplied input/output code: keep it as it is
var input: [String] = []
while let line = readLine() { input.append(line) }
var zoo: [Animal] = []
for line in input {
let p = line.split(separator: ",").map(String.init)
switch p[0] {
case "dog": zoo.append(Dog(name: p[1]))
case "bird": zoo.append(Bird(name: p[1]))
default: zoo.append(Snake(name: p[1]))
}
}
for a in zoo { print(a.describe()) }
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesMethods and selfInitializersClasses Are ReferencesRecap - Library Card4Encapsulation
Access ControlRead-Only From OutsideGuarding StateFailable InitializersRecap - Bank Account7Polymorphism and Generics
PolymorphismType CastingGeneric FunctionsGeneric TypesRecap - Shape Calculator5Inheritance
SubclassesOverriding MethodsInitializers and superfinal and HierarchiesRecap - Employee Hierarchy11Project: Library Management
Books and MembersBorrowing BooksPractice on your own: Swift playground