반응형
참고 사이트: iOS 프로그래밍을 위한 스위프트 기초(edwith)
참고 문서: The Swift Language Guide (한국어)
실행 환경: Xcode 12 실행 → Create a new Xcode project → macOS → Command Line Tool 선택 → Product Name, Organization Identifier 입력 후 프로젝트 생성
목차
- 스위프트(Swift) 5 배워보기 - 1. 다양한 타입
- 스위프트(Swift) 5 배워보기 - 2. 함수, 제어문, 옵셔널
- 스위프트(Swift) 5 배워보기 - 3. 클래스, 구조체, 열거형
- 스위프트(Swift) 5 배워보기 - 4. 클로저
- 스위프트(Swift) 5 배워보기 - 5. 프로퍼티
- 스위프트(Swift) 5 배워보기 - 6. 상속, 인스턴스 생성/소멸
- (계속)
상속
- Swift에서 클래스가 다른 타입과 구분되는 근본적인 요소는 상속(Inheritance)이다.
- 클래스는 메소드, 프로터피 등을 다른 클래스로부터 상속할 수 있다.
- 단일 상속만 가능하며, 다중 상속은 지원하지 않는다.
- 여러 사용법
- final 키워드를 사용하여 재정의(Override)를 방지할 수 있다.
- static 키워드를 사용하여 타입 메소드를 만들면 재정의가 불가능하다.
- class 키워드를 사용하여 타입 메소드를 만들면 재정의가 가능하다.
- class 앞에 final을 붙이면 static 키워드를 사용한 것과 동일하다.
- override 키워드를 사용하여 부모 클래스의 메소드를 재정의할 수 있다.
// 기반 클래스 Person 정의
class Person {
// name 저장 프로피터 선언
var name: String = ""
// selfIntroduce() 메소드 선언
func selfIntroduce() {
print("저는 \(name)입니다")
}
// final 키워드로 재정의 방지
final func sayHello() {
print("hello")
}
// 타입 메소드
// 재정의 불가 타입 메소드 - static
static func typeMethod() {
print("type method - static")
}
// 재정의 가능 타입 메소드 - class
class func classMethod() {
print("type method - class")
}
// 재정의 가능한 class 메소드라도
// final 키워드를 사용하면 재정의 할 수 없다.
// 메서드 앞의 `static`과 `final class`는 똑같은 역할을 합니다
final class func finalCalssMethod() {
print("type method - final class")
}
}
// Person을 상속받는 Student
class Student: Person {
var major: String = ""
override func selfIntroduce() {
print("저는 \(name)이고, 전공은 \(major)입니다")
}
override class func classMethod() {
print("overriden type method - class")
}
// static을 사용한 타입 메소드는 재정의 할 수 없다.
// override static func typeMethod() { }
// final 키워드를 사용한 메소드, 프로퍼티는 재정의 할 수 없다.
// override func sayHello() { }
// override class func finalClassMethod() { }
}
// 객체 생성 후 사용
let nyebo: Person = Person()
let jaehyuk: Student = Student()
nyebo.name = "nyebo"
jaehyuk.name = "jaehyuk"
jaehyuk.major = "Swift"
nyebo.selfIntroduce() // 저는 nyebo입니다
jaehyuk.selfIntroduce() // 저는 jaehyuk이고, 전공은 Swift입니다
Person.classMethod() // type method - class
Person.typeMethod() // type method - static
Person.finalCalssMethod() // type method - final class
Student.classMethod() // overriden type method - class
Student.typeMethod() // type method - static
Student.finalCalssMethod() // type method - final class
인스턴스 생성/소멸
- 인스턴스 생성을 초기화(Initialization), 인스턴스 소멸을 초기화 해지(Deinitialization)라고 한다.
프로퍼티 초기화
- 모든 인스턴스는 초기화와 동시에 모든 프로퍼티에 유효한 값이 할당되어 있어야 한다.
class PersonA {
// 모든 저장 프로퍼티에 기본값 할당
var name: String = "unknown"
var age: Int = 0
var nickName: String = "nick"
}
// 인스턴스 생성
let nyebo: PersonA = PersonA()
// 기본값이 인스턴스가 지녀야 할 값과 맞지 않다면
// 생성된 인스턴스의 프로퍼티에 각각 값 할당
nyebo.name = "nyebo"
nyebo.age = 34
nyebo.nickName = "n"
print(nyebo.name) // nyebo
print(nyebo.age) // 34
print(nyebo.nickName) // n
초기화(init)
- 만약, 초기값을 지정하기 어려운 경우, 초기화(init)를 통해 인스턴스가 생성 시 가져야 할 초기값을 전달할 수 있다.
- 옵셔널 사용 시 초기값을 생략할 수 있다.
class PersonB {
// 저장 프로퍼티 선언 시에 값을 미리 할당하지 않고,
var name: String
var age: Int
var nickName: String // 옵셔널
// init으로 인스턴스 생성 시 필요한 초기값을 전달할 수 있다.
init(name: String, age: Int, nickName: String) {
self.name = name
self.age = age
self.nickName = nickName
}
}
class PersonC {
var name: String
var age: Int
var nickName: String? // 옵셔널
// 옵셔널 지정한 nickName을 생략할 수 있다.
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// init으로 전달된 초기값을 사용하여 인스턴스를 생성할 수 있다.
let jaehyuk: PersonB = PersonB(name: "jaehyuk", age: 34, nickName: "재혁")
let nyebo: PersonC = PersonC(name: "nyebo2", age: 34)
// 인스턴스 생성 후 옵셔널 지정한 nickName에 값을 할당할 수 있다.
nyebo.nickName = "녜보"
print(nyebo.nickName!) // 녜보
- 초기값이 잘못된 경우 인스턴스 생성에 실패할 수 있다. 옵셔널 init?을 사용하면, 인스턴스 생성 실패 시 nil을 반환한다.
class PersonD {
var name: String
var age: Int
var nickName: String?
init?(name: String, age: Int) {
if (0...120).contains(age) == false {
return nil
}
if name.count == 0 {
return nil
}
self.name = name
self.age = age
}
}
let john: PersonD? = PersonD(name: "john", age: 23)
let joker: PersonD? = PersonD(name: "joker", age: 123)
let batman: PersonD? = PersonD(name: "", age: 10)
print(joker) // age 초기값이 기준 범위를 넘어, nil이 반환된다.
print(batman) // name 초기값이 빈 값으로, nil이 반환된다.
- 모든 서브클래스에서 반드시 구현해야 하는 필수 초기값에는 required 키워드를 붙여준다.
class SomeClass {
required init() {
}
}
// 필수초기값을 상속받은 서브클래스에서도 반드시 required 키워드를 붙여
// 다른 서브클래스에게도 이 초기값은 필수초기값이라는 것을 알려야 한다.
class SomeSubclass: SomeClass {
required init() {
}
}
초기화 해제(deinit)
- deinit은 인스턴스가 메모리에서 해제되는 시점에 호출된다.
- 해제 시점은 ARC(Automatic Reference Counting) 규칙에 따라 결정된다.
- deinit을 통해 인스턴스 해제 시점에 해야할 일을 구현할 수 있다.
- 자동으로 호출되므로 직접 호출할 수 없다.
class PersonE {
var name: String
var pet: String
var child: String
init(name: String, pet: String, child: String) {
self.name = name
self.pet = pet
self.child = child
}
// 인스턴스가 메모리에서 해제되는 시점에 자동 호출
deinit {
print("\(name)가 \(child)에게 \(pet)를 인도합니다")
}
}
var donald: PersonE? = PersonE(name: "donald", pet: "happy", child: "jenny")
// donald 인스턴스가 더이상 필요없으므로 메모리에서 해제된다.
donald = nil // donald가 jenny에게 happy를 인도합니다
반응형
'IT' 카테고리의 다른 글
LEMP + TALL(Tailwind, Alpine, Laravel, Livewire) 초기 설정법 (0) | 2021.07.17 |
---|---|
스위프트(Swift) 5 배워보기 - 5. 프로퍼티 (0) | 2021.06.08 |
스위프트(Swift) 5 배워보기 - 4. 클로저 (0) | 2021.06.07 |
[언리얼4] C++ 컴파일이 느린 경우 해결 방법 중 1개 (0) | 2021.06.02 |
스위프트(Swift) 5 배워보기 - 3. 클래스, 구조체, 열거형 (0) | 2020.10.09 |
최근댓글