Полиморфизм
Суть
Полиморфизм — возможность работать с разными типами через один интерфейс: один вызов, разные реализации. «Один интерфейс — много реализаций». В Swift есть четыре практически важных вида.
Виды в Swift
// 1. Subtype polymorphism: class hierarchy, vtable dispatch
class Animal { func sound() -> String { "..." } }
class Dog: Animal { override func sound() -> String { "Woof" } }
// 2. Protocol polymorphism: witness table (existential `any`)
protocol Drawable { func draw() -> String }
struct Square: Drawable { func draw() -> String { "□" } }
struct Dot: Drawable { func draw() -> String { "•" } }
let items: [any Drawable] = [Square(), Dot()]
print(items.map { $0.draw() }.joined()) // □•
// 3. Parametric polymorphism: generics, static dispatch + specialization
func largest<T: Comparable>(_ values: [T]) -> T? { values.max() }
print(largest([3, 9, 2]) ?? 0) // 9
print(largest(["b", "a"]) ?? "") // b
// 4. Ad hoc polymorphism: overloading
func describe(_ x: Int) -> String { "int \(x)" }
func describe(_ x: String) -> String { "string \(x)" }
print(describe(1), describe("a")) // int 1 string a
- Подтипов — подкласс подставляется вместо суперкласса; метод выбирается в рантайме через vtable.
- Протокольный — любой тип, принявший протокол, подходит под
any P; вызов идёт через protocol witness table. Это основной вид полиморфизма в Swift, работает и дляstruct/enum. - Параметрический — дженерики: код пишется один раз для любого
T, компилятор специализирует его под конкретный тип (статическая диспетчеризация, без boxing). - Ad hoc — перегрузка функций и операторов; выбор делает компилятор по типам аргументов.
На что смотрит интервьюер
- Понимание цены: динамическая диспетчеризация (
any P, non-final классы) дешевле, чем кажется, но мешает инлайнингу;some Pи дженерики дают статическую диспетчеризацию. - Методы в
extensionпротокола без требования в самом протоколе диспетчеризуются статически — классическая ловушка: вызов черезany Pвыберет реализацию из extension, а не из типа. final/privateпозволяют компилятору убрать vtable-вызовы (devirtualization).