상속

  • 상속이란? 한 클래스가 다른 클래스의 프로퍼티나 메소드를 물려받아 사용하는 것이다.
  • 상속을 통해 다른 클래스의 프로퍼티나 메소드를 구현하지 않아도 사용이 가능하다.
  • Swift에서는 다중상속을 지원하지 않는다.
class Human {
    var gender: String?
    
    func eat(food: String) {
        print("\(food)를 먹는다.")
    }
}

class Male: Human { //Human 클래스를 상속
    var age: Int = 19
}

var male: Male = Male() //인스턴스 생성
male.age //19
male.gender //nil
male.gender = "남자" //상위 클래스의 프로퍼티 수정
male.gender //남자
male.eat(food: "사과") //사과를 먹는다.
  • 이처럼 클래스를 상속받을 경우 상우 클래스의 프로퍼티나 메소드를 사용할 수 있고, 값도 수정이 가능하다.
  • Swift에서 다중상속은 지원하지 않지만, Male 클래스를 또 다른 클래스가 상속하여 무한으로 상속이 가능하다.

오버라이딩

  • 오버라이딩이란? 상속받은 클래스가 상위 클래스의 프로퍼티나 메소드를 필요에 따라 재정의하여 사용하는 것이다.
  • 오버라이딩은 프로퍼티나 메소드를 선언하기 전 override 키워드를 추가한다.
  • 프로퍼티의 경우 연산 프로퍼티로만 재정의 가능하며 저장 프로퍼티의 경우 기본적으로 값의 제공(get)과 수정(set)이 가능하므로 get과 set이 제공되는 연산 프로퍼티로만 재정의 되어야 한다.
  • get과 set이 제공되던 연산 프로퍼티를 get만 제공하는 프로퍼티로 재정의 하는 것은 불가능하다.
  • 메소드를 재정의하는 경우에는 기존 메소드의 매개변수의 이름, 개수, 타입, 반환값의 타입은 변경할 수 없다.
  • 프로퍼티나 메소드를 재정의하였을때 본래의 기능을 제한하는 방향으로는 불가능하다.
  • 하위 클래스에서 재정의하였더라도 super 키워드를 통해 상위 클래스의 기능을 사용할 수 있다.
class A {
    var name: String = "Class A"
    
    func hello(someString: String) {
        print(someString)
    }
}

class B: A { //A클래스 상속
    override var name: String { //name 재정의
        get {
            return "override Test"
        }
        set {
        }
    }
    
    override func hello(someString: String) { //hello 재정의
        print(someString)
    }
    
    func originName() {
        print(super.name)
}

var classB: B = B()
classB.name //override Test
classB.originName //Class A
classB.hello(someString: "안녕") //안녕
  • 하위 클래스에서의 재정의를 막고자 할 때는 프로퍼티, 메소드 명 혹은 클래스 전체에 final 키워드를 추가하면 된다.
class A {
    final var name: String = "Class A"
    
    func hello(someString: String) {
        print(someString)
    }
}

class B: A {
    override var name: String { //final로 선언된 name 프로퍼티 사용에 따른 오류
        get {
            return "override Test"
        }
        set {
        }
    }
    
    override func hello(someString: String) {
        print(someString)
    }
    
    func origin() {
        print(super.name)
    }
}

final class A {
    var name: String = "Class A"
    
    func hello(someString: String) {
        print(someString)
    }
}

class B: A { //final로 선언된 클래스 A 상속에 따른 오류
    override var name: String {
        get {
            return "override Test"
        }
        set {
        }
    }
    
    override func hello(someString: String) {
        print(someString)
    }
    
    func origin() {
        print(super.name)
    }
}