Notice
Recent Posts
Recent Comments
Link
大器晩成
클래스의 상속 (Inheritance) 본문
- 객체지향에서 상속을 정의하면 '한 클래스가 다른 클래스에서 정의된 프로퍼티나 메서드를 물려받아 사용하는 것'이라고 할 수 있습니다.
- 상속을 사용하면 이미 만들어진 다른 클래스의 기능이나 프로퍼티를 직접 구현하지 않고도 사용할 수 있으며, 추가로 필요한 기능이나 프로퍼티만 정의하여 사용하면 됩니다.
- 이때 기능이나 프로퍼티를 물려주는 클래스와 이를 상속받는 클래스 사이에서는 다음과 같은 관계가 성립됩니다.
- 프로퍼티와 메서드를 물려준 클래스는 부모 클래스 = 상위 클래스 = 슈퍼 클래스 = 기본 클래스
- 프로퍼티와 메서드를 물려받은 클래스는 자식 클래스 = 하위 클래스 = 서브 클래스 = 파생 클래스
- 상속은 유일하게 클래스에서만 지원하는 기능입니다.(구조체는 상속 불가능)
- 상속은 본질적으로 성격이 비슷한 타입을 새로 만들어 데이터(저장속성)를 추가하거나, 기능(메서드)을 변형시켜서 사용하는 것입니다.
클래스를 상속하는 과정
class A {
var name = "Class A"
var description: String { // 읽기전용으로 설정된 연산 프로퍼티
get {
return "This class name is \(self.name)"
}
}
func foo () {
print("\(self.name)'s method foo is called")
}
}
let a = A() //상수 a에는 클래스 A로부터 만들어진 인스턴스가 할당
a.description
a.foo()
// 서브 클래싱
// 클래스 A를 상속 받아 새로운 클래스를 정의하는 과정을 서브클래싱이라고 한다.
// 즉 서브클래싱이란 기존에 있는 클래슬르 기반으로 하여 새로운 클래스를 작성하는 과정이다.
/*
class <클래스 이름> : <부모클래스> {
//추가로 구현할 내용
}
*/
// 스위프트는 단일 상속만 지원이 된다.
class B: A {
var prop = "Class B"
func boo() -> String {
return "Class B pror = \(self.prop)"
}
}
let b = B()
b.prop // Class B
b.boo() // Class B pror = Class B
b.name // Class A
b.foo() // Class A's method foo is called
b.name = "Class C"
b.foo() // Class C's method foo is called
- 어떤 클래스도 상속받지 않는 클래스를 정의한다. 이 클래스를 기본(부모) 클래스라고 합니다.
- 클래스 B에는 name 프로퍼티와 foo 메서드가 정의되어 있지 않음에도 불구하고, 인스턴스 b는 이들을 사용합니다.
- 심지어 프로퍼티에 값을 대입하는 것도 가능합니다.
- 클래스 B가 A를 상속받음으로써 모든 프로퍼티와 메서드를 물려받았기 때문이다. 정리해 보면 서브크래싱 과정을 통해 메서드를 상속받은 클래스 B의 현재 상태는 다음과 같습니다.
Class B의 현재 상태
// name, description 프퍼티와 foo 메소드는 직접 정의한 것이 아닌 클래스 A로부터 물려 받은 것이다.
// 이때의 클래스 A를 B의 부모 클래스, 또는 슈퍼 클래스라고 하고 클래스 B를 A의 자식 클래스, 또는 서브 클래스라고 한다.
class B {
var name = "Class A"
var prop = "Class B"
var description: String { // 읽기전용으로 설정된 연산 프로퍼티
get {
return "This class name is \(self.name)"
}
}
func foo () {
print("\(self.name)'s method foo is called")
}
func boo() -> String {
return "Class B pror = \(self.prop)"
}
}
상속의 금지 키워드 final
final class Dog {
var name = "뽀삐"
final var age = 10
}
class Cat: Dog { // Error: Inheritance from a final class 'Dog'
}
- Inheritance from a final class 'Dog' - final 키워드로 선언된 클래스는 상속이 불가능합니다.
- 클래스의 상속 금지의 키워드 final (final를 각 멤버 앞에 붙인 경우, 해당 멤버 재정의 불가라는 뜻)
- 경우에 따라서, 클래스의 상속을 금지해야 하는 경우가 있습니다.
상속의 간단한 예시
class Person {
var id = 0
var name = "이름"
var email = "abc@gmail.com"
}
class Student: Person {
// id
// name
// email
var studentId = 0
}
class Undergraduate: Student {
// id
// name
// email
// studentId
var major = "전공"
}
// 상위 클래스에서 존재하는 멤버를 변형하는 것을 재정의라고 함
// 재정의를 하려는 멤버에는 override 키워드를 붙여야함 (자세한 내용은 다음 강의에서 다룰 예정)
- 기본적으로 상속은 데이터(저장 속성)를 추가하는 관점에서 생각하면 편합니다.
상속에 대한 개념적 예제
- 자동차나 자전거, 또는 오토바이 등에 대한 클래스를 만든다고 할 때, 이들을 공통적인 개념으로 묶을 수 있습니다. 바로 '탈 것(Vehicle)', 또는 교통수단'이라는 개념입니다. 따라서 기본 클래스로 '탈 것'에 대한 객체를 구현하여 여기에 기본 속성과 기능을 부여하게 되면 자전거나 자동차 등 구체적인 객체를 만들려면 탈 것에 대한 객체를 바탕으로 서브클래싱하여 속성이나 기능을 덧붙이기만 하면 됩니다.
class Vehicle {
var currendSpeed = 0.0 //저장 속성이며, 현재의 속도를 저장
var description: String { //읽기 속성
return "시간당 \(self.currendSpeed)의 속도로 이동하고 있습니다."
}
func makeNoise() { // Vehicle 함수에서는 기능이 없지만, 서브클래싱을 통해 자식클래스에서는 기능을 만들 예정
//임의의 교통수단 자체는 경적을 울리는 기능이 필요 없다.
}
}
let baseVehicle = Vehicle()
baseVehicle.description //시간당 0.0의 속도로 이동하고 있습니다
class Bicycle: Vehicle {
var hasBasket = false
}
let bicycle = Bicycle()
bicycle.hasBasket = true
// 자전거 객체의 현재 속도를 설정
bicycle.currendSpeed = 20.0
print("자전거: \(bicycle.description)") //자전거: 시간당 20.0의 속도로 이동하고 있습니다.
// 기본 클래스 Vehicle뿐만 아니라 자식 클래스인 Bicycle 역시 다른 클래스의 부모 클래스가 될 수 있다.
// Bicycle을 부모클래스로 하여 새로운 클래스를 서브클래싱할 수도 있다.
// Bicycle을 기반으로 서브클래싱된 새로운 자식 클래스는 Bicycle의 프로퍼티나 메소드를 상속 받을 뿐만 아니라 Bicycle 클래스의 부모 클래스인 Vehicle 클래스의 프로퍼티나 메소드 까지 모두 상속 받는다.
class Tandem: Bicycle { //Tandem: 2인용 자전거
var passengers = 0
}
tandem.hasBasket = true
tandem.passengers = 2
tandem.currendSpeed = 14.0
print("Tandem: \(tandem.description)") //Tandem: 시간당 14.0의 속도로 이동하고 있습니다.
Tandem 클래스는 Bicycle 클래스의 메서드와 프로퍼티뿐만 아니라 그 부모 클래스인 Vehicle의 메서드와 프로퍼티까지 모두 상속받았습니다. 이 때문에 예제에서처럼 모든 프로퍼티를 사용할 수 있습니다. Bicycle 클래스를 상속받은 Tandem의 프로퍼티와 메서드를 모두 표현하면 다음과 같다.
Tandem B의 현재 상태
class Tandem {
var currendSpeed = 0.0
var hasBasket = false
var passengers = 0
var description: String { //읽기 속성
return "시간당 \(self.currendSpeed)의 속도로 이동하고 있습니다."
}
func makeNoise() { // Vehicle 함수에서는 기능이 없지만, 서브클래싱을 통해 자식클래스에서는 기능을 만들 예정
//임의의 교통수단 자체는 경적을 울리는 기능이 필요 없다.
}
}
- 이러한 메서드와 프로퍼티들의 일부는 Bicycle로부터, 일부는 Vehicle로부터, 그리고 나머지는 Tandem에서 직접 정의한 것들이다. 이 관계를 표현하면 다음과 같다.
- Vehicle > Bicycle > Tandem
- (CurrentSpeed, desciption, makeNoise()) (hasBasket) (passeengers)
728x90
'iOS > Swift 문법' 카테고리의 다른 글
재정의(오버라이딩) - 메서드 (0) | 2024.11.27 |
---|---|
재정의(오버라이딩,Overriding) - 속성(프로퍼티) (0) | 2024.11.26 |
구조체와 클래스(let, var) 참고자료 (0) | 2024.11.25 |
싱글톤패턴 (Singleton Pattern) (0) | 2024.11.25 |
접근 제어 (Access Control) (0) | 2024.11.25 |