Swift의 서브클래싱과 익스텐션의 개요

2 분 소요

상속, 클래스, 그리고 하위 클래스

무제_page-0001 베이스 클래스(base class) or 루트 클래스(root class): 최상위 클래스
하위 클래스(subclass) or 자식 클래스(child class): 상속받은 클래스
상위 클래스(super class) or 부모 클래스(parent class): 하위 클래스가 상속받은 클래스
단일 상속(single inheritance): 하위 클래스는 반드시 단 한 개의 부모 클래스만 둘 수 있음


상속 예제

BankAccount 클래스 - 부모 클래스

class BankAccount {
     
    var accountBalance: Float
    var accountNumber: Int
     
    init(number: Int, balance: Float) {
        accountNumber = number
        accountBalance = balance
    }
     
    func displayBalance() {
        print("Number \(accountNumber)")
        print("Current balance is \(accountBalance)")
    }
}

SavingsAccount 클래스 - 자식 클래스

class SavingsAccount: BankAccount {
 
}

부모인 BankAccount 클래스의 모든 메서드와 프로퍼티를 실제로 상속받음


하위 클래스의 기능 확장하기

새로운 프로퍼티와 메서드 추가

class SavingsAccount: BankAccount {
     
     var interestRate: Float = 0.0
     
     func calculateInterest() -> Float {
         return interestRate * accountBalance
     }
}

상속받은 메서드 오버라이딩하기

오버라이드(override): 필요한 정확한 기능을 제공하기 위한 수정작업
메서드를 오버라이딩을 할 때 반드시 따라야 할 두 가지 규칙

  1. 하위 클래스의 오버라이딩 메서드는 오버라이딩되는 부모 클래스 메서드의 매개변수 개수, 타입과
    정확하게 일치
  2. 오버라이딩하는 메서드는 반드시 부모 클래스 메서드가 반환하는 타입과 일치
 class SavingsAccount: BankAccount {
     
     var interestRate: Float = 0.0
     
     func calculateInterest() -> Float {
         return interestRate * accountBalance
     }
     
     override func displayBalance() {
         print("Number \(accountNumber)")
         print("Current balance is \(accountBalance)")
         print("Prevailing interest rate is \(interestRate)")
     }
 }

override 키워드가 앞에 붙은 displayBalance 메서드의 새로운 버전을 SavingsAccount 클래스에 선언

super : 부모 클래스에 있는 인스턴스를 하위 클래스에서 호출하기 위해 사용

override func displayBalance() {
    super.displayBalance()
    print("Prevailing interest rate is \(interestRate)")
}

코드의 중복을 없앨 수 있음


하위 클래스 초기화하기

하위 클래스에서 추가된 변수를 초기화할 필요가 있음

class SavingsAccount: BankAccount {
     
    var interestRate: Float = 0.0
     
    init(number: Int, balance: Float, rate: Float) {
        interestRate = rate
        super.init(number: number, balance: balance)
    }
.
.
.
}

항상 하위 클래스의 초기화 작업이 완료된 후, 부모 클래스의 init 메서드를 호출!
잠재적인 문제를 피하기 위해


SavingsAccount 클래스 사용하기

let savings1 = SavingsAccount(number: 12311, balance: 600.00, rate: 0.07)

print(savings1.calculateInterest()) // 600 * 0.07 = 42.0
savings1.displayBalance()
 /*
  Number 12311
  Current balance is 600.0
  Prevailing interest rate is 0.07
  */

스위프트 클래스 익스텐션

익스텐션(extension): 스위프트 클래스에 새로운 기능을 추가하는 또 다른 방법

  • 하위 클래스를 생성하거나 참조하지 않고 기능을 추가

extension CalssName {
    // 기능 추가
}

Ex)

extension Double {
     
    var squared: Double { // 제곱 값을 반환
        return self * self
    }
     
    var cubed: Double { // 세제곱 값을 반환
        return self * self * self
    }
}
 
let myValue: Double = 3.0
print(myValue.squared) // 9.0
  • 값에서 프로퍼티로 직접 접근 가능
print(3.0.squared) // 9.0
print(6.0.cubed) // 216.0


장점: 하위 클래스를 사용하지 않고 클래스의 기능을 확장할 수 잇는 빠르고 편리한 방법
단점: 클래스에 있는 기존의 기능을 오버라이드할 수 없음, 저장 프로퍼티를 포함할 수 없음