Dog foot print

[SWIFT] 상속 본문

IOS/Swift

[SWIFT] 상속

개 발자국 2021. 7. 15. 22:56

상속이란 ?

클래스에서만 가능한 기능으로 상속은 특정 클래스의 메서드와 프로퍼티를 그대로 물려 받는 것 으로 정리가 가능합니다. 그래서 상속은 정의를 물려주는 클래스와 물려 받는 클래스가 존재하는데, 각각 슈퍼 클래스서브 클래스 로 불리웁니다. 이를 번역 할 때 다른 이름으로 불리기도 하는데, 이를 정리하면 다음과 같습니다.

  • 하위클래스 == 서브클래스 == 자식클래스 == 파생 클래스
  • 상위클래스 == 슈퍼클래스 == 부모클래스 == 기본 클래스

상속을 받기 위한 class 를 정의 하는 것은 다음과 같습니다.

class [name] : [상속받을 클래스] {
    정의 부분
}

만약 : 옆에 있는 클래스 이외에 다른 것이 있다면 이는 protocol 구현을 위한 구문 입니다.

Ex :

class SuperClass{
    var name = "Class A"

    var description : String {
        return "this class is \(self.name)";
    }

    func foo(){
        print("\(name)'s foo called")
    }
}

class SubClass : SuperClass{

}

let a = SubClass();
a.name //Class A
a.foo() //SubClass
a.description //this class is Class A

오버라이딩

overriding이란 서브 클래스에서 슈퍼 클래스에서 정의되어 있는 메소드나 프로퍼티를 다시 재정의 하는 것을 의미합니다. swift에서는 override를 할 때는 꼭 재정의 할 대상앞에 override 예약어를 붙여주어야 합니다. 이는 개발자가 실수로 슈퍼클래스의 프로퍼티나 메서드를 재 정의 하는것을 방지 하기 위함입니다.
만약 슈퍼클래스에서 정의되어 있지 않는 프로퍼티나 메서드를 override하게 되면 에러를 발생 시킵니다.

프로퍼티가 오버라이딩 될 수 있는 조건은 다음과 같습니다.

  • 저장 프로퍼티를 get, set구문이 모두 있는 연산 프로퍼티로 오버라이딩 하는 것
  • get, set 구문이 모두 제공되는 연산 프로퍼티를 get, set 구문이 모두 제공되는 연산 프로퍼티로 오버라이딩 하는 것
  • get 구문만 제공되는 연산 프로퍼티를 get, set구문이 모두 제공되는 연산 프로퍼티로 오버라이딩 하는 것
  • get 구문만 제공되는 연산 프로퍼티를 get 구문만 제공되는 연산 프로퍼티로 오버라이딩 하는 것

프로퍼티가 오버라이딩 될 수 없는 조건은 다음과 같습니다.

  • 저장프로퍼티를 저장 프로퍼티로 오버라이딩 하는 것
  • get , set구문과 관계없이 연산 프로퍼티를 저장 프로퍼티로 오버라이딩 하는 것
  • 저장 프로퍼티를 get 구문만 제공되는 연산 프로퍼티로 오버라이딩 하는 것
  • get, set 구문을 모두 제공하는 연산프로퍼티를 get구문만 제공되는 연산 프로퍼티로 오버라이딩 하는 것 .

즉 오버라이딩은 확장의 개념이며, 기존의 것을 제한 하는 행위는 하면 안됩니다.

Ex : )

import UIKit

class BasicHumanInfo{
    var name = "";
    var birth = 1994;

    var age : Int {
        get{
            let formatter = DateFormatter();
            formatter.dateFormat = "yyyy";
            return Int(formatter.string(from: Date()))! - birth + 1;
        }
        set{
            let formatter = DateFormatter();
            formatter.dateFormat = "yyyy";
            birth = Int(formatter.string(from: Date()))! - newValue;
        }
    }


}

class American : BasicHumanInfo{
    override var age : Int {
        get{
            let formatter = DateFormatter();
            formatter.dateFormat = "yyyy";
            return Int(formatter.string(from: Date()))! - birth;
        }
        set{
            let formatter = DateFormatter();
            formatter.dateFormat = "yyyy";
            birth = Int(formatter.string(from: Date()))! - newValue;
        }
    }
}

let a = American();
a.age

Note : get, set이 존재하는 연산 프로퍼티를 오버라이딩 할때는 하위 클래스에서 set이 하는것이 없더라도, set을 명시해주어야 합니다.

Note : 상수나, 읽기 전용 프로퍼티가 아니라면 옵저버 프로퍼티로 오버라이딩 할 수 있다. 그러나, 연산프로퍼티를 옵저버 프로퍼티로 오버라이딩 하여도, 연산프로퍼티가 없어지는 것은 아니다.

import UIKit

class BasicHumanInfo{
    var name = "";
    var birth = 1994;

    var age : Int {
        get{
            let formatter = DateFormatter();
            formatter.dateFormat = "yyyy";
            print("누군가가 age를 호출 하였다.")
            return Int(formatter.string(from: Date()))! - birth + 1;
        }
        set{
            let formatter = DateFormatter();
            formatter.dateFormat = "yyyy";
            print("누군가가 age를 변경하였다.")
            birth = Int(formatter.string(from: Date()))! - newValue;
        }
    }


}

class American : BasicHumanInfo{
    override var age : Int {
        willSet{
            print("\(age)가 \(newValue)로 변경 됩니다.")
        }
        didSet{
            print("\(oldValue)가 \(age)로 변경 되었습니다.")
        }
    }
}

let a = American();
a.age = 10;

//누군가가 age를 호출 하였다. age
//누군가가 age를 호출 하였다. oldValue
//28가 10로 변경 됩니다. willset
//누군가가 age를 변경하였다. set
//누군가가 age를 호출 하였다. age
//28가 11로 변경 되었습니다. didset

메서드 오버라이딩

메서드가 오버라이딩 될 수 없는 조건은 다음과 같습니다 .

  • 재정의할 메서드에서 식별자를 변경 하는 것
  • 파라메터의 타입을 변경 하는 것,
  • 리턴 타입을 변경 하는 것
  • 파라메터의 개수를 변경 하는 것

즉 메서드가 오버라이딩 되려면 내부 구현만 변경해야 합니다.

오버로딩이라는 단어와 매우 혼동되고는 하는데, 오버 로딩은 같은 이름을 가진 함수가 파라메터의 개수, 파라메터 각각의 타입, 반환 타입이 하나라도 다른 경우에는 서로 다른 함수로 인식 하는 것을 의미합니다. 그렇기에, 오버라이딩의 정의는 같은 멤버를 확장하는 개념인데, 만약 위의 조건에 부합하지 않게 되면 전혀 다른 메서드를 오버라이딩 하게 되는 것과 동일 합니다 .

Ex : )

import UIKit

class BasicHumanInfo{

    func makeSomeNoise(){
        print("소리 질러 !!!")
    }

}

class American : BasicHumanInfo{

    override func makeSomeNoise() {
        print("booya !!!")
    }
}

let a = American();
a.makeSomeNoise()

#swift

반응형

'IOS > Swift' 카테고리의 다른 글

[SWIFT] 초기화  (0) 2021.07.20
[SWIFT] Type casting  (0) 2021.07.20
[SWIFT] 메서드  (0) 2021.07.13
[SWIFT] 프로퍼티  (0) 2021.07.13
[SWIFT] 구조체와 클래스  (0) 2021.07.13
Comments