class Animal {
    var eating: String = "Can eat"
    var digest: String = "Can Digest"
    var breathing: String = "Can Breath"
}

class Human: Animal {
    var thinking: String = "Can Think"
    var speaking: String = "Can Speak"
}

let tiger = Animal()
let logan = Human()

슈퍼 클래스로부터 상속을 받으면 상속받은 멤버를 자유롭게 사용할 수 있었습니다.
그래서 Human타입으로 인스턴스를 생성해도, Animal 멤버에 접근할 수 있었습니다.
클래스 계층과 상속 링크

Type Check

Human is Animal 사람은 동물이다. 라고말하면 자연스럽지만,
Animal is Human 동물은 사람이다. 라고말해버면 어딘가 어색해집니다.

다시 코드를 보고 상속 계층에 적용해본다면, Child Class에서 Parent Class와의 타입은 호환되지만, 그 반대의 경우는 불가능합니다.

위 코드에서 Animal 클래스와 Human 타입으로 인스턴스를 각각 한 개씩 생성했습니다.
그리고 is 연산자를 사용해 타입 체크를 했습니다.

logan is Animal // true
logan is Human // true

tiger is Animal // true
tiger is Human // false

is 연산자는 런타임에 타입을 체크하기때문에, 최종결과를 확인하기 위해선 코드를 실행해봐야 합니다.
두 피연산자의 타입이 서로 호환되거나(toll-free-bridge), 왼쪽 피연산자의 타입이 오른쪽 피연산자 형식과 동일한 상속 계층에 있고 오른쪽 피연산자가 더 상위 클래스라면 true가 리턴됩니다.

UP Casting

업캐스팅은 동일한 상속계층에서 서브클래스 인스턴스를 Superclass 타입으로 저장하는 것을 의미합니다.

let cage = [tiger, logan]

cage 배열 안에 tiger와 logan을 같이 넣어두었습니다.
tiger와 logan은 각각 타입이 Animal과 Human입니다. 하지만 배열은 1가지 타입만 저장할 수 있는 특징을 가지고 있습니다.

그래서 Animal을 상속한 Human타입이 Animal로 '업캐스팅' 되어 배열에 저장(다형성)되었습니다.
업캐스팅은 타입 어노테이션으로 직접 지정해줄 수도 있습니다.

다형성: 모든 요소가 동일한 상속 계층에 있다면, 가장 인접한 슈퍼 클래스로 업캐스팅 되어 배열의 타입이 결정됩니다.

let logan: Animal = Human()

인스턴스를 생성할 때, 슈퍼 클래스의 타입을 명시적으로 적어주면서 선언하면 됩니다.
업캐스팅은 상속계층이 같다면, 항상성공합니다. 그리고 멤버의 접근 범위는 업캐스팅 된 클래스로 제한됩니다.

DOWN Casting

logan은 Human이지만, 지금은 Animal로 업캐스팅 되어있기 때문에,
Human의 멤버인 thinking과 speaking엔 접근할 수 없습니다.

본래 타입 멤버에 접근해야 하는 경우 as 연산자를 사용해 다운캐스팅을 해주면 됩니다.

as 연산자는 왼쪽 피연산자의 타입이 오른쪽 타입과 호환된다면 오른쪽 타입으로 캐스팅 된 인스턴스를 리턴해줍니다. 이 때 새로운 인스턴스가 리턴되는 것이 아닌, 이미 존재하는 인스턴스에서 오른쪽 피연산자 타입에 선언되어 있는 멤버만 접근할 수 있는 임시 인스턴스가 리턴됩니다.

if let humanLogan = logan as? Human {
    print(humanLogan.thinking)
}

// Prints: Can Think

as? 연산자를 사용해 logan을 Human타입으로 다운캐스팅을 시도했습니다.
다운캐스팅이 성공한다면 humanLogan에 임시 인스턴스로 저장됩니다. 임시 인스턴스를 통해 다시 thinking 속성에 접근할 수 있습니다.

Type Casting

동일한 상속 계층은 아니지만 as연산자를 통해 호환되는 형식을 캐스팅하는 경우는 타입캐스팅이라고 합니다.

profile
iOS개발자 꿈나무

0개의 댓글