- 클래스만의 특성
- 말그대로 하나의 클래스가 다른 클래스에게 물려주는 것
- 한 클래스가 다른 클래스에서 정의된 프로퍼티나 메서드를 물려받아 사용하는 것
- 프로퍼티나 메서드를 물려주는 쪽: 부모 클래스 = 상위 클래스 = 슈퍼 클래스 = 기본 클래스
- 프로퍼티나 메서드를 물려받는 쪽: 자식 클래스 = 하위 클래스 = 서브 클래스 = 파생 클래스
class A {
var name = "Class A"
var description: String {
return "This class name is \(self.name)"
}
func foo() {
print("\(self.name)'s method foo is called")
}
}
let a = A()
a.name //Class A
a.description //This class name is Class A
a.foo() //Class A's method foo is called
기존의 클래스를 상속받아 새로운 클래스를 정의하는 행위
class <클래스 이름> : <부모 클래스> {
//추가로 구현할 내용
}
class B: A {
var prop = "Class B"
func Boo() -> String {
return "Class B prop = \(self.prop)"
}
}
let b = B()
b.prop //Class B
b.Boo //Class B prop = Class B
b.name //Class A
b.name = "Class C"
b.foo() //Class C's method foo is called
📚 클래스 B는 클래스 A를 상속받음
📚 클래스 B가 클래스 A를 상속받음으로써 클래스 A의 모든 프로퍼티와 메서드를 물려받음
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "시간당 \(self.currentSpeed)의 속도로 이동하고 있습니다"
}
func makeNoise() {
}
}
let baseVehicle = Vehicle()
baseVehicle.description //시간당 0.0의 속도로 이동하고 있습니다
class Bicycle: Vehicle {
var hasBasket = false //자전거 바구니 부착 여부
}
let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 20.0
print("bicycle: \(bicycle.description)")
//bicycle: 시간당 20.0의 속도로 이동하고 있습니다
📚 Vehicle
클래스 상속받음
📚 Vehicle
클래스의 프로퍼티 상속받음
class Tandem: Bicycle {
var passengers = 0
}
let tandem = Tandem()
tandem.hasBasket = true
tandem.passengers = 2
tandem.currentSpeed = 14.0
print("tandem: \(tandem.description)")
//tandem: 시간당 14.0의 속도로 이동하고 있습니다
📚 Bicycle
클래스를 상속받는 Tandem
클래스는 Bicycle
의 프로퍼티나 메서드뿐만 아니라, Bicycle
클래스의 부모 클래스인 Vehicle
클래스의 프로퍼티나 메서드까지 상속받음을 알 수 있음
- 상속받은 프로퍼티나 메서드를 그대로 사용하지 않고 다시 구현하거나 재정의하는 과정
- 이때의 변경이 부모 클래스에까지는 적용되지 않음
- 자기 자신과 자신을 서브클래싱한 하위 클래스에만 적용됨
- 메서드나 프로퍼티 선언 앞에 override 키워드 사용
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "시간당 \(self.currentSpeed)의 속도로 이동하고 있습니다"
}
func makeNoise() {
}
}
class Car: Vehicle {
var gear = 0
var engineLevel = 0
override var currentSpeed: Double {
get {
return Double(self.engineLevel*50)
}
set {
}
}
override var description: String {
get {
return "Car: engineLevel = \(self.engineLevel), so currentSpeed: = \(self.currentSpeed)"
}
set {
print("New Value is \(newValue)!")
}
}
}
let c = Car()
c.engineLevel = 5
c.currentSpeed //250
c.description = "New Class Car"
📚 클래스 Car
은 클래스 Vehicle
을 상속받음
📚currentSpeed
는 부모 클래스에서 저장 프로퍼티로 정의되어 있었으므로, 오버라이딩할 때 연산 프로퍼티의 형태로 바뀌어야 함
📚 description
프로퍼티는 읽기 전용 프로퍼티였는데, 오버라이딩할 때 읽기 쓰기가 모두 가능한 연산 프로퍼티의 형태로 바꾸었음
📚 description
에 값을 할당하면, set 구문이 실행된다
class Bike: Vehicle {
override func makeNoise() {
print("빠라빠라빠라밤")
}
}
let bk = Bike()
bk.makeNoise()
//빠라빠라빠라밤
- 상속받은 부모 클래스의 인스턴스를 참조할 수 있는 객체
- 오버라이딩 되기 전 본래의 프로퍼티나 메서드를 사용할 수 있음
- 메서드나 프로퍼티 앞에 super 객체를 이용하여 참조(ex. super.메서드이름)
- 메서드나 프로퍼티가 하위 클래스에서 오버라이딩되는 것을 차단하는 키워드
- 더는 수정하거나 기능을 변경하기를 원하지 않을 경우 사용
- 보안 문제와 같은 이유로 사용하는 경우도 있음
- 프로퍼티나 메서드 정의 앞에 키워드 작성
같은 이름을 가진 메서드여도 정의된 매개변수의 타입이 다르면 서로 다른 메서드로 처리
func makeNoise()
func makeNoise(param: Int)
func makeNoise(param: String)
func makeNoise(param: Double) -> String
📚 위의 메서드들은 컴파일러에 의해 서로 다른 메서드로 처리됨
=> 오버라이딩 시, 메서드의 매개변수 개수, 타입, 반환타입, 순서 모두 변경하면 안 되는 이유!
출처)
꼼꼼한 재은 씨의 스위프트: 문법편