/* 오버라이딩 하지 않았을 때 */
class Person {
func say() {
print("hi")
}
}
class Noah: Person { }
let a: Person = Noah()
a.say() // hi
/* 오버라이딩 했을 때 */
class Noah: Person {
override func say() {
print("hi Noah")
}
}
let b: Person = Noah()
b.say() // hi Noah
클래스처럼 상속의 개념이 적용된다
컴파일 타임에는 메서드의 선언만 알고,
역시 런타임에 메서드의 정의를 찾아야 한다
그 인스턴스에 맞는 메서드를 찾아서 호출해야 한다
protocol Person {
func say()
}
struct A: Person {
func say() {
print("a a a")
}
}
struct B: Person {
func say() {
print("b b b")
}
}
let a: Person = A()
let b: Person = B()
a.say() // a a a
b.say() // b b b
오버라이딩 자체가 불가능하기 때문에,
extension에서 선언한 메서드가 불리는 게 보장된다
즉, Static Dispatch
class Person {
func say() {
print("hi")
}
}
extension Person {
func sayYes() {
print("yes!")
}
}
class Man: Person {
override func sayYes() { // Error!
}
}
따라서 어느 한 타입에서만 불린다고 보장되지 않기 때문에 Dynamic Dispatch
protocol Person {
func say()
}
extension Person {
func say() {
print("this is default hi")
}
}
class Man: Person { }
class Woman: Person {
func say() {
print("this is woman hi")
}
}
let a: Person = Man.init()
let b: Person = Woman.init()
a.say() // this is default hi
b.say() // this is woman hi
인스턴스의 타입이 프로토콜일 때, 무조건 extension에서 구현한 메서드가 실행된다
즉, 해당 클래스에서 아무리 같은 메서드를 작성했더라도 extension에서 구현한 메서드가 불리는 것이 보장되기 때문에 Static Dispatch이다
(주의) 변수의 타입이 클래스이면, 클래스에서 구현한 메서드가 실행된다
protocol Person { }
extension Person {
func say() {
print("newly say")
}
}
class Man: Person { }
class Woman: Person {
func say() {
print("woman say")
}
}
let a: Person = Man.init()
let b: Person = Woman.init()
let c: Woman = Woman.init()
a.say() // newly say
b.say() // newly say
c.say() // woman say