swift문법

[Swift] Part12_클래스(상속과 초기화)

화찌님 2022. 8. 23. 01:39

1. 클래스의 상속과 재정의

수직확장: 본질적으로 성격이 비슷한 타입으르 새로 만들어 데이터(저장속성)을 추가하거나, 기능(메서드)를 변형시켜서 사용하려는것

//부모클래스
class Persom {
	var id = 0
    var name = "이름"
    var eamil = "abc@email.com"
}

//상속


//자식클래스
class Student: Person {
	//id변수존재
    //name변수존재
    //email변수전재
    var studentId = 0
}

 

스위프트는 다중상속 불가능

 

상속은 추가적으로 필요한 데이터(저장속성)을 늘린다는 관점에서 생각해야함

데이터(저장속성)은 추가만 가능

기능(메서드)는 추가 및 변형(대체)가능 >> 메서드들은 상속이 되면서 새로운 배열로 저장되기 때문

 


2. 초기화의 과정과 생성자

class Dog {
	var name: String
    var weight: Double
    ...
    init(name: String. weight: Double) {
    	self.name = name
        self.weight = weight
    }
    ....
}

< 초기화메서드(생성자) >

함수의 구현이 특별한 키워드인 init으로 명명됨

인스턴스를 생성과정: 저장속성에 대한 초기값을 설정하여 사용간으한 상태가 되는것

생성자 메서드 실행 목적은, 모든 저장속성 초기화를 통한 인스턴스 생성

설계도(클래스, 구조체, 열거형)을 실제로 사용하기 위해 인스턴스를 찍어내는 과정

 

<생성자 직접 구현하지 않으면>

사용자 정의구현이 일단 원칙

-모든 저장속성에 기본값 전제

클래스: 기본생성자 init()제공

구조체: 기본생성자 init()제공 + 멤버와이즈이니셜라이저도 기본제공

-일부저장속성에 기본값 전제

클래스: 원칙적으로 일부 값만 가지고, 생성자 구현하지 않는 방법이 존재하지 않음

구조체: 멤버와이즈 이니셜라이저 기본제공

 

<구조체/ 클래스의 생성자/ 소멸자 비교>

지정생성자: (구조체/클래스)init() { }

편의생성자: (구조체)없음.   (클래스)convenience init(파라미터) { }

필수생성자: (구조체)없음.   (클래스)required init(파라미터) { }

실패가능생성자: (구조체/클래스)init?(파라미터) { }  또는 init!(파라미터) { }

소멸자: (구조체)없음.   (클래스)deinit{ }

 

1) 지정생성자

class Dog { 
	var name: String
    var weight: Double
    ...
    init(name: String, weight: Double) {
    	self.name = name
        self.weight = weight
    }
}

init(....)형태를 가진 생성자

지정생성자는 모든 저장 속성을 초기화해야함

오버로딩이 가능함으로, 다양한 파라미터 조합으로 지정생성자 구현 가능

따로 지정하지 않아도 모든 저장속성이 초기화되는 경우, 기본생성자 자동제공 >> init()

생성자를 1개이상 구현하며녀 기본 생성자를 제공하지 않음

 

2)편의생성자 - 상속관련

class Dog {
	var name: String
    var weight: Double
    ...
    convenience init() {
    	self.init(...)
    }
    ...
}

서브개념의 생성자

지정생성자의 의존 및 호출

초기화 과정을 간편하게 제공하기 위함

서브클래스에서 재정의를 못함

편의생성자는 다른 편의생성자를 호출하거나, 지정생성자를 호출해야함 (결론적으로 마지막엔 지정생성자를 꼭 호출해야함)

상속관계에서 개바자가 실수할수있는 여러 가능성을 배제하기 위한 생성자.

모든 속성을 초기화하지 않는다면 >> 편의생성자 만드는것이 복잡도의 실수를 줄일 수 있음

결국, 생성자를 가능한 중복을 줄이고 다른 생성자를 호출하는 패턴으로 구현해야함

 

<상속관계에서 생성자 위임의 규칙>

1단계 메모리 초기화(값설정)

2단계 커스텀설정(설정값 바꾸거나, 메서드 실행)

 

 

3)필수생성자 - 상속과 관련

class Dog {
	var name: String
    var weight: Double
    ...
    requried init() {
    	self.name = "강아지"
        self.weight = 10.0
    }
    ...
}

클래스 생성자 앞에 requried키워드를 붙이면 하위클래스에서 반드시 해당 생성자(파라미터 이름 및 타입이 동일)를 구현해야함

하위클래스에서 필수생성자 구현시, override키워드 필요없이 reequired키워드만 붙이기 !

필수생성자 자동상속 조건: 다른 지정 생성자를 구현 안하면, 자동으로 필수생성자 상속됨

 

4) 실패가능생성자

class Dog {
	var name: String
    ...
    init?(name: String) {
    	if name.isEmpty {
        	return nil
        }
        self.name = name
    }
    ....
}

실패가능성을 가진 생성자

실패시 nil을 리턴

init에 ?를 붙어 init?(...)로 정의

실패불가능 생성자는 다른 실패가능 생성자를 호출 불가능 >> 범위때문에

init! == init? 임

 

5)소멸자

class Dog {
	deinit {
    	print("객체의 소멸")
    }
}

인스턴스 해제시, 정리가 필요한 내용을 정의

클래스에는 최대 1개의 소멸자가 존재

힙에서 해제될때 자동으로 호출되는 메서드 부분

객체가 사라지는지 확인할때 소멸자에 print를 넣어서 확인을 많이 함


<대원칙>

저장속성 재정의 불가

메서드는 재정의 가능(다만, 기능 축소는 불가능)

 

1) 저장속성

재정의 불가 >> 메모리구조에서 상위구현을 참조하기 때문에

예외적으로, 메서드형태로 부수적 추가는 가능 >> 계산속성형태로 재정의가능 / 속성감시자형태로 재정의 가능

 

2) 계산속성

실질적 메서드

계산속성의 재정의는 실질적 메서드 대체 >> 재정의 가능

확장방식의 재정의 가능. 단 기능축소는 불가능

 

3) 생성자

생성자는 기본적으로 상속되지않고 재정의 원칙

상위지정생성자와 현재단계의 저장속성을 고려해서 구현

1단계

(상위)지정생성자: 재정의 필수 고려 (1.지정 2.편의 3.안할지)

(상위)편의생성자: 재정의 불가(호출불가) 

2단계

(현단계의)모든저장속성 초기화 및 상위의 지정 생성자 호출

(편의생성자 구현시) 지정생성자를 호출

 

예외상황 >> 생성자 자동 상속

지정생성자 자동상속 >> 저장속성 기본값 설정 및 어떤 재정의도 하지 않았을때

편의생성자 자동상속 >> 상위 지정생성자를 모두 상속하는 경우

 


이 포스팅은 인프런에있는 엘런의 스위프트를 참고하여 작성하였습니다.