[Swift] 상속과 오버라이딩

민니·2022년 7월 5일
0

Swift 문법

목록 보기
10/17

상속 ❓

  • 클래스만의 특성
  • 말그대로 하나의 클래스가 다른 클래스에게 물려주는 것
  • 한 클래스가 다른 클래스에서 정의된 프로퍼티나 메서드를 물려받아 사용하는 것
  • 프로퍼티나 메서드를 물려주는 쪽: 부모 클래스 = 상위 클래스 = 슈퍼 클래스 = 기본 클래스
  • 프로퍼티나 메서드를 물려받는 쪽: 자식 클래스 = 하위 클래스 = 서브 클래스 = 파생 클래스

📚 Example

  • 기본 클래스
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 <클래스 이름> : <부모 클래스> {
	//추가로 구현할 내용
}
  • Example
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의 모든 프로퍼티와 메서드를 물려받음


예제를 통해 더 알아보자!

  • 자동차, 자전거, 오토바이 등에 대한 클래스를 만든다고 할 때, 이들의 공통적인 개념은 <탈 것>이라는 것임
  • 기본 클래스로 <탈 것>에 대한 객체를 구현하고, 자동차나 자전거 같은 구체적인 객체를 만들 때, 탈 것에 대한 객체를 바탕으로 서브클래싱하여 필요한 속성이나 기능만 덧붙이면 되지 않을까?
  • Vehicle(탈 것) 기본 클래스 정의
class Vehicle {
	var currentSpeed = 0.0
    
    var description: String {
    	return "시간당 \(self.currentSpeed)의 속도로 이동하고 있습니다"
    }
    
    func makeNoise() {
    }
}

let baseVehicle = Vehicle()
baseVehicle.description //시간당 0.0의 속도로 이동하고 있습니다

  • Bicylce 클래스 정의
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 클래스의 프로퍼티 상속받음


  • Tandem 클래스 정의
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 키워드 사용

프로퍼티 오버라이딩

  • 프로퍼티를 오버라이딩할 때는 무조건 연산 프로퍼티의 형태로 오버라이딩할 것
  • 특히 저장 프로퍼티는 get, set 구문이 모두 있는 프로퍼티로 오버라이딩
  • 상위 클래스의 기능을 하위 클래스가 확장 또는 변경만 할 수 있음, 제한은 ❌
  • 프로퍼티 옵저버도 구현 가능
  • Example
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 구문이 실행된다



메서드 오버라이딩

  • 메서드의 매개변수 개수, 타입, 반환타입, 순서는 변경 ❌ -> 오버로딩 때문! (포스트 마지막 부분 참고)
  • 오로지 내부 구문들만 변경 가능
  • Example
class Bike: Vehicle {
    override func makeNoise() {
        print("빠라빠라빠라밤")
    }
}

let bk = Bike()
bk.makeNoise()
//빠라빠라빠라밤

Super

  • 상속받은 부모 클래스의 인스턴스를 참조할 수 있는 객체
  • 오버라이딩 되기 전 본래의 프로퍼티나 메서드를 사용할 수 있음
  • 메서드나 프로퍼티 앞에 super 객체를 이용하여 참조(ex. super.메서드이름)

final

  • 메서드나 프로퍼티가 하위 클래스에서 오버라이딩되는 것을 차단하는 키워드
  • 더는 수정하거나 기능을 변경하기를 원하지 않을 경우 사용
  • 보안 문제와 같은 이유로 사용하는 경우도 있음
  • 프로퍼티나 메서드 정의 앞에 키워드 작성


오버로딩 ❓

같은 이름을 가진 메서드여도 정의된 매개변수의 타입이 다르면 서로 다른 메서드로 처리

  • Example
func makeNoise()
func makeNoise(param: Int)
func makeNoise(param: String)
func makeNoise(param: Double) -> String

📚 위의 메서드들은 컴파일러에 의해 서로 다른 메서드로 처리됨
=> 오버라이딩 시, 메서드의 매개변수 개수, 타입, 반환타입, 순서 모두 변경하면 안 되는 이유!







출처)
꼼꼼한 재은 씨의 스위프트: 문법편

0개의 댓글