라티의 작은 일기장

[6일차] 상속 본문

Swift

[6일차] 상속

코드라티 2023. 2. 25. 23:37

오늘은 거실에서 공부 시작

개강 전 까지 Swift의 기본 문법을 다루는 챕터 1을 끝내야하는데... 오늘이 지나고 나면 딱 4일 남게 된다.

토요일임에도 불구하고 교육이 있었기에 나는 오늘 놀았다고는 할 수 없지만 평일보다는 여유롭다고 말할 수 있기에, 오늘은 Swift에서의 상속(Inheritance)은 여타 객체지향 언어들과 어떤 차이가 있는지 알아보려 한다.

 

상속(Inheritance)?

거의 모든 CS 전공인들이 언어를 막론하고 이 "상속"에 대해 처음 접할 때, "부모 클래스의 내부 변수, 메소드 등을 자식 클래스에 물려주는 것"이라는 설명을 듣는데, 개인적으로는 이러한 설명이 좀 지양됐으면 좋겠다. 물려준다니.. 여기서 상속의 행동 주체는 부모 클래스가 아니라 자식 클래스임을 상속에 대해서 조금만 공부해도 알게되는데, 저 설명은 꼭 부모 클래스가 상속을 해줘야만 프로퍼티를 활용할 수 있다는 듯 들린다. 뭐 아무튼, 다시 돌아오면 Swift에서 상속 또한 타 언어에서의 상속과 크게 다르지 않다.

 

코드를 통해 상속의 예시를 확인해보자.

class Vehicle {
    var currentSpeed = 0.0
    var desctiption: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makenoise() {
        
    }
}

우선 상속에서 부모 클래스로 활용할 클래스 Vehicle을 하나 정의하였다.

그리고 자식 클래스는 아래와 같이 정의할 수 있다.

class 클래스 이름: 부모클래스 이름 {
	하위 클래스 정의
}

하위 클래스 정의 부분에서는 부모 클래스에는 없는데 필요에 따라 추가적인 프로퍼티를 정의할 코드를 작성한다.

위 구조에 따라 Vehicle을 상속받는 자식 클래스 Bicycle을 정의하고, hasBasket이라는 신규 프로퍼티를 추가하였다.

다음의 실행 결과를 확인해보자.

Bicycle 클래스의 인스턴스 bicycle을 선언하고, 상속 받은 프로퍼티 currentSpeed를 확인 및 변경해보았다.

또한 자식 클래스에서 새롭게 정의한 hasBasket 프로퍼티의 내용도 확인해보았다.

잘 변경되고, 확인되는 것이 보여진다.

 

다음으로 함수 오버라이딩(function override)을 위한 예시를 확인해보자.

Vehicle을 상속 받는 두번째 자식 클래스 Train을 정의하였다.

class Train: Vehicle {
    override func makenoise() {
        print("choo choo~~")
    }
}

Vehicle의 프로퍼티인 makenoise() 메소드를 오버라이딩하여, "choo choo~~"라는 문자열을 출력하도록 하였다.

실행 결과를 확인해보자.

이렇게 기차 소리가 잘 출력되는 것을 확인할 수 있다.

 

그런데 만약, 자식 클래스(sub class)에서 부모 클래스(super class)의 프로퍼티를 활용하고 싶을 땐 어떻게 할까?

답은... super 키워드를 활용하면 된다.

우선 부모 클래스의 makenoise() 메소드를 변경하여 어떤 문자열을 출력하도록 해보고, 자식 클래스에서 해당 메소드를 호출해보자.

class Vehicle {
    var currentSpeed = 0.0
    var desctiption: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makenoise() {
        print("Speaker on")
    }
}

class Train: Vehicle {
    override func makenoise() {
        super.makenoise()
        print("choo choo~~")
    }
}

let train = Train()
train.makenoise()

실행 결과는 다음과 같다.

 

그렇다면 함수가 아니라 프로퍼티를 재정의하려면 어떻게 해야할까?

함수 오버라이딩과 개념은 같지만 방식에서 약간의 차이를 보인다.

프로퍼티 오버라이딩을 할 때는 프로퍼티를 직접 재정의 하는 것이 아닌, getter / setter 형식으로 재정의한다.

예시 코드를 통해 확인해보자.

class Car: Vehicle {
    var gear = 1
    override var desctiption: String {
        return super.desctiption + " in gear \(gear)"
    }
}

let car = Car()
car.currentSpeed = 30.0
car.gear = 2
print(car.desctiption)

부모 클래스의 desciption을 getter 형식으로 받아와서 description 프로퍼티를 재정의하는 코드이다.

인스턴스 선언 및 프로퍼티 초기화, 프로퍼티 내용 출력에 대한 실행 결과는 다음과 같다.

추가로, 프로퍼티 오버라이딩을 통해 프로퍼티 옵저버를 설정하는 방법에 대해서도 알아보자.

예시 코드는 다음과 같다.

 

class AutomaticCar: Car {
    override var currentSpeed: Double {
        didSet {
            gear = Int(currentSpeed / 10) + 1
        }
    }
}

let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.desctiption)")

 

Car 클래스의 currentSpeed를 오버라이딩하고, didSet 옵저버를 통해 currentSpeed의 값에 따라 gear값을 변경하도록 했다.

인스턴스 생성 후 currentSpeed에 35.0을 할당한 뒤 gear의 변화값을 확인하기 위해 description을 출력해보았다.

예상대로 잘 변경된 것을 확인할 수 있었다.

 

마지막으로, 이런 오버라이딩을 방지하고 싶으면 변수, 메소드 또는 클래스나 구조체, 열거형 앞에 final 키워드를 붙여주면 된다.

오늘 공부 끝~

 

 

 

패스트캠퍼스 바로가기 : http://bit.ly/3Y34pE0

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

> 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

'Swift' 카테고리의 다른 글

[8일차] 프로토콜  (0) 2023.02.27
[7일차] assert와 guard  (0) 2023.02.26
[5일차] 프로퍼티  (0) 2023.02.24
[4일차] 초기화 구문 init()  (0) 2023.02.23
[3일차] 구조체와 클래스  (0) 2023.02.22