Swift의 재정의(override)

썹스·2022년 10월 14일
0

Swift 문법

목록 보기
19/68

재정의(override)

  • Swift에서 재정의(override)는 상위 클래스의 프로퍼티 또는 메서드를 가져와서 수정하는 것을 의미합니다.

  • 프로퍼티의 경우에는 상위 클래스의 저장 속성(Stored Properties)을 수정할 수 없지만, 계산 속성(Computed Properties)의 경우에는 부분적인 재정의(기능 확장만)가 가능합니다.

  • 프로퍼티 또는 메서드 앞에 "override" 키워드를 작성하여 재정의를 할 수 있습니다.

  • "super" 키워드를 사용하여 상위 클래스의 메서드를 호출할 수 있습니다.


📌 메서드의 재정의

메서드 재정의 및 상위 클래스의 메서드 호출

class A{
    var a: Int = 1
    func hello(){
        print("저는 A입니다.")
    }
}

class B: A{
    var b: Int = 10
    override func hello() {  // 재정의
        print("저는 B입니다.")
    }
}

class C: A{
    var c: Int = 100
    override func hello() {  // 재정의
        super.hello()        //상위 클래스의 메서드 호출
        print("저는 C입니다.")
    }
}

var kim = A()
var lee = B()
var park = C()

kim.hello()   //저는 A입니다.
lee.hello()   //저는 B입니다.
park.hello()  //저는 A입니다.(super 키워드에 의한 호출)    \n저는 C입니다.

사실 메서드(생성자 init제외)의 재정의는 비교적 간단하고, 큰 문제 없이 재정의를 할 수 있으므로 자유롭게 재정의할 수 있지만, 프로퍼티는 조금 다릅니다.


📌 프로퍼티의 재정의

Swift에서 저장 속성은 재정의가 불가능 하지만, 상속받은 저장 속성을 계산 속성으로 재정의하여 사용할 수 있습니다. (계산 속성은 사실 함수라서 재정의가 가능하며, 기능의 확장 여부에 따라 재정의 여부가 달라집니다.)

상위 클래스재정의 방향하위 클래스재정의 여부
저장 속성➡️계산 속성(get 또는 get/set)재정의 가능
계산 속성(get)➡️계산 속성(get/set)재정의 가능
계산 속성(get/set)➡️계산 속성(get)재정의 불가능

저장 속성 -> 계산 속성(get/set)으로 재정의

class A{
    var a: Int = 10
    func hello(){
        print("a입니다.")
    }
}

class B: A{
    override var a: Int{
        get{
            return super.a
        }
        set{
            super.a = newValue
        }
    }
}

var kim = B()
kim.a         // 10
kim.a = 100   // 저장 속성을 하위 클래스에서 계산 속성으로 재정의하여 프로퍼티 데이터 수정

kim.a         // 100

계산 속성(get) -> 계산 속성(get/set)

class A{
    var defaultValue = 10
    var a: Int{
        return defaultValue * 2
    }
}

class B: A{
    override var a: Int{
        get{
            return super.a
        }
        set{
            defaultValue = newValue
        }
    }
}

var kim = B()
kim.a         // 20

kim.a = 100   //
kim.a         // 200

kim.a = 5     //
kim.a         // 10

계산 속성(get/set) -> 계산 속성(get)

🚨에러 발생: Cannot override mutable property with read-only property 'a'

기능을 추가하여 계산 속성을 확장하는 것은 가능하지만, 기능을 축소하여 재정의하는것은 불가능합니다.

class A{
    var defaultValue = 10
    var a: Int{
        get{
            return defaultValue * 2
        }
        set{
            defaultValue = newValue
        }
    }

}

class B: A{
    override var a: Int{  //에러 발생 Cannot override mutable property with read-only property 'a'
        get{
            return defaultValue * 10
        }
    }
}

계산 속성 외에도 저장 속성을 속성 감시자로 재정의하여 사용할 수 있습니다. (속성 감시자의 동작 원리가 함수이기 때문에 재정의가 가능)


왜 프로퍼티의 재정의는 까다롭고, 메서드의 재정의는 자유로울까??🤔

그 이유는 클래스의 메모리 구조와 동작 방법 때문입니다

기본적으로 프로퍼티와 메서드의 클래스 정보(틀, 거푸집)는 메모리의 데이터(Data) 영역에 저장되어 있습니다. 이렇게 클래스 정보로부터 만들어진 인스턴스의 데이터(프로퍼티값)는 힙(Heap)영역에 저장됩니다.

그렇다면 프로퍼티 또는 메서드를 재정의한다면 어떻게 될까??🤔

하위 클래스의 인스턴스는 데이터 영역에 존재하는 상위 클래스의 정보에 직접적으로 접근할 수 없습니다. 이 말은 프로퍼티가 상위 클래스의 메모리 구조에 관여할 수 없으므로 재정의할 수 없다는 것을 의미합니다.(상위 클래스의 프로퍼티를 상속받아 사용하기 때문에 재정의할 권한이 없음)

하지만 계산 속성과 속성 감시자의 경우에는 메모리 구조의 프로퍼티를 수정하는 것이 아닌 기능을 추가하는 방식이기 때문에 일부 허용됩니다.

메서드의 경우에는 함수의 기능이 코드(Code)영역에 저장되어 사용하기 때문에 재정의를 자유롭게 할 수 있습니다. (함수의 기능이 코드영역에 있어 상속으로 얽혀있는 메모리 구조에 접근할 일이 없음)



Reference

참고자료: 앨런 Swift문법 마스터 스쿨

profile
응애 나 코린이(비트코인X 코딩O)

0개의 댓글