본문 바로가기
카테고리 없음

[복습] Part 12. 클래스의 상속과 초기화 | 상속, 재정의, 초기화, 생성자, 소멸자, init, deinit

by 23g 2024. 9. 8.

내가 직접 코드로 안치니까

자꾸 까먹어서 확실히 복습하기!

클래스의 상속

class Animal {
    var name: String
}

//Bird는 Animal을 상속 받음
class Bird: Animal{
    //name
    var color: String
}

 

재정의 

 - 오버라이딩(overriding)
(영어 뜻: 재정의) 클래스의 상속에서 상위클래스의 속성/메서드를 재정의(기능을 약간 변형하여 사용)하는 것

 

 재정의 규칙

1. 저장 속성 : 재정의 불가

2. 계산 속성 : 확장 방식의 재정의 가능 (실질적 매서드여서)

3. 생성자 : 재정의가 원칙 (원칙상 상속X)

4. 메서드 : 재정의 가능 super.init

 

==> 속성과 메서드는 재정의 방식이 다름 ⭐️

 

class Aclass{
    
    var aValue = 1
    func doSomething(){
        print("hello")
    }
}

class Bclass: Aclass{
    // 재정의
    override func doSomething() {
        print("hi")
    }
    //원래 저장 속성은 재정의 불가하나
    // 저장 속성을 계산 속성의 형태로 재정의 가능함
    override var aValue: Int{
        get {
            return 1
        }
        set {
            super.aValue = newValue
        }
    }
}

 

초기화

: 저장 속성의 초기값을 설정하여 사용 가능한 상태가 되게하는 인스턴스 생성 과정

 

초기화 매서드 (=생성자)

: init 으로 명명

- 목적 : 저장 속성에 대한 초기값을 설정하여 사용 가능한 상태가 되게 함

- 인스턴스를 찍어내는 과정

 

1) 지정 생성자 

class Person{
    var name: String
    var age: Int
    
    //지정 생성자
    init(name: String, age: Int){
        self.name = name
        self.age = age
    }
}

 

2) 편의 생성자

class에서만 사용, 다른 생성자 호출시 필수로 붙여야함!,

편리하게 인스턴스를 찍어낼 수 있음, 내부에서 self.init() 호출, 지정 생성자에 의존함

class Person{
    var name: String
    var age: Int
    
    init(name: String, age: Int){
        self.name = name
        self.age = age
    }
    //편의 생성자
    convenience  init() {
        self.init(name: "홍길동", age: 25)
    }
}

 

상속 관계에서 생성자 위임 규칙 ! ⭐️

[1단계 - 상위 생성자에 대한 고려]
 - 상위에 어떤 지정 생성자가 존재하는지?
 //🍑 아래 셋 중 하나 택 일
 - (상위) 지정 생성자 ===> 1) 하위클래스에서 지정 생성자로 구현 (재정의)
 -                              ===> 2) 하위클래스에서 편의 생성자로 구현 가능 (재정의)
 -                              ===> 3) 구현 안해도됨(반드시 재정의하지 않아도 됨)
 - (상위) 편의 생성자 ===> 재정의를 하지 않아도 됨 (호출 불가가 원칙이기 때문에 재정의 제공 안함)
 -                              ===> (만약에 동일한 이름을 구현했다면) 그냥 새로 정의한 것임
[2단계 - (현재단계의) 생성자 구현]
 - 1) 지정 생성자 내에서
 -   ===> (1) 나의 모든 저장 속성을 초기화해야함
 -   ===> (2) 슈퍼 클래스의 지정 생성자 호출
 - 2) 편의 생성자 내에서
 -   ===> 현재 클래스의 지정생성자 호출 해야함 (편의 생성자를 거치는 것은 상관없음)
          (결국 지정 생성자만 모든 저장 속성을 초기화 가능)

 

class Aclass {
    var x = 0
    // 기본 생성자가 자동으로 제공됨
    // init() {}                
}

class Bclass: Aclass {
    
    var y: Int

    // 🎾 [1단계] 상위의 지정생성자 고려 ==============================
    // 상위에 동일한 이름이 있으므로 재정의 해야함 (이 형태는 안됨)
//    init() { }
    
    // (선택 1) 지정생성자로 재정의
    override init() {       // 상위 클래스와 "이름이 동일한 생성자" 구현은 재정의만 가능함(올바른 재정의) (지정생성자로 구현)
        //🍑 현재 단계의 저장 속성 고려
        self.y = 0 
        //🍑 하위 지정 생성자는 반드시 상위 지정 생성자 호출해야함(델리게이트 업)
        super.init() 
    }
    
    // (선택 2) 서브클래스에서 편의생성자로 구현해보기
    // 상위 클래스와 "이름이 동일한 생성자" 구현은 재정의만 가능함(올바른 재정의) (지정생성자 필요)
    override convenience init() {
    	// 🍑 편의생성자는 나의 단계에 있는 지정 생성자를 호출해야함(델리게이트 어크로스)
        self.init(y: 0) 
    }
    
    // (선택 3) 재정의 하지 않을 수도 있음 (상속안함)
    
    
    // 🎾 [2단계] (현재단계의) 생성자 구현 ============================
    
    init(y: Int) {
        self.y = y
        super.init()
    }

}

 

필수 생성자

: required 키워드가 붙으면 무조거 하위에서 구현해야함

class Aclass {
    var x: Int
    // 필수 생성자
    required init(x: Int) {
        self.x = x
    }
}

class Bclass: Aclass{
    var y: Int
    //하위에서 구현!
    required init(x: Int) {
        self.y = 0
        super.init(x: x)
    }
}

 

실패 가능 생성자

 

실패 가능 -> 실패 불가능 (O)

실패 불가능 -> 실패 가능 (X)

: 실패 불가능한 애가 실패 가능한 것을 호출하는 것이 말이 안되기 때문에 불가능

 

[ 동일 단계/ 상속 관계에서 호출 ]

내가 실패 가능(?)하면 내로남불

: 실패 가능하던 불가능(?)하던 상관 없음

내가 실패 불가능(?)하면 끼리끼리임

: 실패 불가능(?)만 ok, 실패 가능은 안됨 

 

[ 상속 관계시 재정의 ]

상위 ? 시 하위 실패 불가능 재정의 가능 (강제 언래핑 활용)

: 작은 범위  큰 범위이기 때문

상위 실패 불가능 시 하위 ? 불가능 ! 

: 큰 범위 ⊄ 작은 범위라서

// 상위 : 생성자 / 하위 : 실패 가능 생성자 예시
class Product {
    var name: String
    init(name: String) {
        //if name.isEmpty { return nil }
        self.name = name
    }
}

class Item: Product{
    var quantity: Int
    
    init?(name: String, quantity: Int){
        self.quantity = quantity
        super.init(name: name)
    }
}

 

소멸자

: 인스턴스가 메모리에서 제거되기 직전에 자동으로 호출되는 메서드 

class Qrcode {
    deinit {
        print("해당 코드가 소멸됨")
    }
}

var a: Qrcode? = Qrcode()
a = nil

 

 

오늘 팥 19강까지 복습하려고 했는데

하루종일 팥12함,,,,큰일남

최근댓글

최근글

skin by © 2024 ttutta