ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift - Inheritance (상속)
    Programming/Swift 2021. 11. 11. 00:24

     

     

    안녕하세요 BeePeach입니다 :)

    오늘은 class에서만 사용 가능한 특별한 기능 중에 하나인 Inheritance(상속)에 대해서 공부를 해보려 합니다.

     

    class는 method, property 등을 다른 class에게 상속시킬 수 있습니다.

    이때 물려주는 class를 superclass, parentclass, 물림을 받는 class를 subclass childclass라고 합니다.

    Swift에서는 한 subclass가 2개 이상의 superclass를 가질 수 없습니다.

     

    그럼 상속에 대해서 천천히 알아보도록 하겠습니다.

     

     


    Base Class

     

    Base class란 아무것도 상속받지 않은 class를 말합니다.

     

     

    저장 프로퍼티, 연산 프로퍼티, 메서드를 가지는 Figure라는 baseClass를 만들어 보았습니다.

    기존에 우리가 선언한 class와 다를 건 없습니다. 아무것도 상속받지 않는 class일 뿐입니다.

     

    Figure 클래스는 흡사 Abstract class(추상 클래스)처럼 이 클래스 혼자서 딱히 뭔가 하는 게 없어 보입니다.

    그래서 인스턴스를 생성해서 멤버들에 접근해도 딱히 얻어갈 건 없는 거 같네요.

    다른 언어를 하셨던 분이라면 그럼 이 클래스를 abstract class로 만들면 되잖아??라고 생각하실 수 있지만

    Swift에서는 따로 제공되지 않습니다. 대안으로 주로 protocol을 사용합니다.

     

    다시 돌아와서 이제 정말 상속을 사용해보려고 합니다.

    Figure class에서 상속을 받은 다른 class를 생성해 보겠습니다.

     

     


    Syntax

     

    문법은 아주아주 간단합니다.

    class를 정의할 때 이름 옆에 :과 상속받을 class의 이름을 적어주면 됩니다.

    당연히 이미 정의가 된 className을 적어줘야겠죠??


    그럼 바로 예시를 보도록 하겠습니다.

     

     

    Figure 클래스를 상속한 Circle 클래스를 만들었습니다.

    Circle이니까 반지름을 나타내는 radius 프로퍼티도 추가시켜주면 좋을 거 같네요.

    지금까지의 class라면 radius 프로퍼티만 선언했으니 radius 프로퍼티에만 접근이 가능하겠죠?? 한번 확인해 볼까요??

     

     

    radius 프로퍼티에 접근하는 건 당연히 되는데... 선언하지도 않은 name 프로퍼티와 draw 메서드에도 접근이 가능합니다.

     

    상속을 받으면 superClass에 선언한 멤버들을 모두 사용할 수 있습니다.

    심지어 그 멤버들을 수정할 수 도 있습니다.

    name 프로퍼티를 "Circle"로 변경했고 그 결과 description 연산 프로퍼티의 출력 결과도 바뀌는 것을 볼 수 있습니다.

     

    당연히 상속을 받은 Circle 클래스도 sub class를 가질 수 있습니다.

    BaseClass만 상속을 시켜줄 수 있는 게 아닙니다.

     

     

    이렇게 subClass여도 다른 subClass를 가질 수 있습니다.

    딱히 의미 없는 CustomCircle 클래스를 생성했습니다.
    Circle로부터 물려받은 멤버들을 사용할 수도 있지만 Circle의 superClass인 Figure의 멤버도 사용할 수 있습니다.

     

     


    override

     

    다시 Circle 클래스로 돌아와서 생각을 해보면 draw 메서드가 매우 마음에 들지 않습니다.

    Figure 클래스는 도형이라는 추상적인 개념을 다루니 뭘 그릴지 모르지만 Circle 클래스는 아닙니다.

     

    draw 메서드를 호출하면 🔵을 나타내고 싶습니다.

    그럼 어떻게 할까요??

    이때 사용하는 개념이 바로 override(재정의)입니다.

     

    Override란 인스턴스 메서드, 타입 메서드, 인스턴스 프로퍼티, 타입 프로퍼티, 서브스크립트등 superClass로부터 상속받은 멤버들을 새롭게 다시 정의하는 것을 말합니다.

    완전히 새롭게 다시 정의하는 것도 가능하고 superClass에서 정의된 내용에서 기능을 추가하는 것도 가능합니다.

     

    Override를 하는 방법은 매우 간단합니다.

    override 키워드만 원하는 멤버 선언부에 추가시켜주면 됩니다.

    당연히 이미 superClass에 존재하는 멤버여야 합니다.

    Override가 불가능한 멤버라면 컴파일 에러가 발생해서 오류를 알 수 있습니다.

     

     

    Circle 클래스에서 draw 메서드를 override 했습니다.

    그리고 draw 메서드를 호출하니 우리가 원하는 대로 🔵이 나오는 것을 확인할 수 있습니다.

    그럼 한번 프로퍼티도 override 해볼까요??

     

     

    먼저 computedProperty인 description을 보겠습니다.

    마찬가지로 override 키워드를 추가시켜주고 getter, setter를 원하는 대로 바꿔주면 됩니다.

     

    주의할 점을 한 가지만 말씀드리면 superClass에서 read-write computedProperty로 작성했다면  subClass에서도 read-write computedProperty로  override 해야 합니다.

    반대로  superClass에서 read-only computedProperty로 작성했다면 subClass에서는 read-write, read-only computedProperty로 모두 override 할 수 있습니다.

    (한 번 직접 해 보시 것도 추천드립니다.)

     

    그런데 문제는 stored Property를 override 할 때 발생합니다.

    Line 13처럼 작성하면 에러가 발생합니다.

    Stored Property를 override 하고 싶다면 Line 15와 같이 getter와 setter를 사용해야 합니다.

    위 예시의 코드는 딱히 의미있는 코드는 아니지만 getter와 setter를 사용해야 한다는 예시를 보여드리기 위해서 작성했습니다.

     

     


    super 

     

    위의 방법은 super Class의 구현을 무시하고 완전히 새롭게 정의하는 방법입니다.

    그럼 기존 superClass의 구현에 더해서 기능을 추가하려고 하면 어떻게 하면 될까요??

     

    이때 유용하게 사용할 수 있는 프로퍼티가 super입니다.

     

    이전에 우리는 self에 대해서 공부한 적이 있습니다.

    super 프로퍼티는 이와 비슷하게 자동으로 제공해주는 프로퍼티입니다.

     

    super를 이용해여 superClass에서 정의한 멤버들에 접근할 수 있습니다.

     

     

    예제를 보면 CustomCircle 클래스에서 draw 메서드를 override하고 있습니다.

    이전과 다른 부분이라면 super.draw() 코드가 추가된거네요.

     

    super.draw()를 이용하면 superClass의 draw메서드를 호출할 수 있습니다.

    그럼 superClass인 Circle에서 draw 메서드는 🔵를 그리는 것이었습니다.

    여기에 🔴를 그리도록 추가를 해서 원래 있던 기능에 우리가 원하는 기능을 추가시킨 것을 확인할 수 있습니다.

     

     


    상속과 override를 금지하는 방법

     

    만약 상속을 금지시키고 싶다면 어떻게 할까요??

    class 앞에 final 키워드를 작성한다면 이 클래스 상속할 수 없게 됩니다.

     

     

    final 키워드는 어떤 멤버를 override를 할 수 없도록 만들고 싶을 때도 사용합니다.

    이번에는 class 앞이 아닌 final var, final func와 같이 선언 키워드 앞에 작성해주면 됩니다.

    그럼 해당 멤버만 override가 불가능하게 됩니다.

     


     

    참고자료

     

    https://kxcoding.com

     

    여러분의 새로운 도전을 응원합니다 | KxCoding

    Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기

    kxcoding.com

     

     

    https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html

     

    Inheritance — The Swift Programming Language (Swift 5.6)

    Inheritance A class can inherit methods, properties, and other characteristics from another class. When one class inherits from another, the inheriting class is known as a subclass, and the class it inherits from is known as its superclass. Inheritance is

    docs.swift.org

     

     

     

    728x90

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

    Swift - Initializer Delegation  (0) 2021.11.28
    Swift - Initializer 기초  (1) 2021.11.13
    Swift - Subscript  (0) 2021.11.07
    Swift - Method  (0) 2021.11.06
    Swift - Property Wrapper Projecting Value  (0) 2021.11.05
Designed by Tistory.