참고 자료
전역변수 문제점, 나쁜 객체지향 코드 (유지보수 망침) 스티븐이 TIL에 공유해준 링크 👍
Singleton Pattern이 전역변수를 사용하는 데 있어서 가장 효과적이라고 함
(전역변수 문제점 해결에 효율적)
super.init()은 상속받은 클래스에서 상속한 클래스의 프로퍼티를 재정의(?) 하고 싶을 때
(예를 들면, 아래와 같이 다른 초기값을 넣어주고 싶을 때)
사용하는 것으로 이해함
import Foundation
class Vehicle {
var numberOfWheels = 0
var description: String {
return "\(numberOfWheels) wheel(s)"
}
}
let vehicle = Vehicle()
print("Vehicle: \(vehicle.description)") // Vehicle: 0 wheel(s)
저장 프로퍼티 numberOfWheels에는 초기값으로 0을 지정해줬지만,
연산 프로퍼티 description에는 초기값을 지정하지 않음.
이런 경우에 Vehicle 클래스는 자동으로 default initializer을 받아서 description에 0을 넣어줘서 인스턴스를 생성하게 해줌 ?!
class Bicycle: Vehicle {
override init() {
super.init()
numberOfWheels = 2
}
}
Bicycle은 Vehicle의 자식 클래스
Bicycle 버전의 이니셜라이즈다라는 걸 override로 나타냄
Bicycle의 init()은 super.init()을 호출하면서 시작됨
super.init()은 Bicycle 클래스의 superclass인 Vehicle의 default initializer를 호출함
우선은 numberOfWheels라는 상속받은 property가 Vehicle에 의해 initialize 되게함
→ Bicycle이 numberOfWheels 프로퍼티를 수정하기 전에
이제 super.init()을 호출한 다음에는 numberOfWheels의 초기값이 0이었다가 새로운 값인 2로 교체됨!
let bicycle = Bicycle()
print("Bicycle: \(bicycle.description)")
// Bicycle: 2 wheel(s)
Bicycle의 인스턴스를 생성하고, 상속받은 description 연산 프로퍼티를 호출해봄
numberOfWheels 값이 0에서 2로 업데이트 된 걸 알 수 있음
Hoverboard라는 Vehicle을 상속받는 다른 클래스를 만들어봄
(참고로 호버보드는 전동 바퀴가 달린 보드라고 함)
class Hoverboard: Vehicle {
var color: String
init(color: String) {
self.color = color
// super.init() implicitly called here
}
override var description: String {
return "\(super.description) in a beautiful \(color)"
}
}
let hoverBoard = Hoverboard(color: "pink")
print("Hoverboard: \(hoverBoard.description)")
// Hoverboard: 0 wheel(s) in a beautiful pink
Hoverboard의 initializer에서는 오직 color 프로퍼티만 정의해줌
대놓고 super.init()을 호출하는 대신에, 암시적인 호출을 해줌
암시적인 호출이 override var로 description을 정의한 걸 얘기하는 건가?
아무튼 이런 식으로 해주는 방법도 있다고 합디다 !
출처: Swift 공식문서 - Initialization
인스턴스 프로퍼티 vs. 타입 프로퍼티
매번 우리가 타입의 새로운 인스턴스를 만들 때마다, 이 인스턴스는 자기만의 프로퍼티 밸류 세트를 가지고 있는 거임 (다르 인스턴스를 만들면 그 아이는 또 자기만의 세트가 생기는 거고)
이 프로퍼티는 타입에 속하는 것이지, 타입의 그 어떤 인스턴스에도 속하는 게 아님
내가 타입의 얼마나 많은 인스턴스를 만드는지 간에
이 프로퍼티는 하나의 copy만 있을 거임 !
Q. 타입 프로퍼티는 왜 쓰는거임?
타입 프로퍼티는 특정 타입의 모든 인스턴스에게 공통적으로 적용되는 (일반적으로 쓰이는) 값을 정의할 때 유용함
타입 프로퍼티를 정의할 때 static 키워드를 써줌 !
import Foundation
struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 1
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 6
}
}
class SomeClass {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
return 27
}
class var overrideableComputedTypeProperty: Int {
return 107
}
}
타입 프로퍼티도 인스턴스 프로퍼티 같이 .(dot)으로 접근할 수 있음
그런데 타입 프로퍼티는 타입에 세팅된건지
타입의 인스턴스에 세팅된게 아님
print(SomeStructure.storedTypeProperty) // Some value.
SomeStructure.storedTypeProperty = "Another value"
print(SomeStructure.storedTypeProperty) // Another value
print(SomeEnumeration.computedTypeProperty) // 6
print(SomeClass.computedTypeProperty) // 27
At a minimum, every operation object should implement at least the following methods:
main
Methods to override for concurrent operations
main
(Optional) This method is typically used to implement the task associated with the operation object. Although you could perform the task in the start
method, implementing the task using this method can result in a cleaner separation of your setup and task code.
Method overriding
Method overriding is a language feature in which a class can provide an implementation of a method that is already provided by one of its parent classes. The implementation in this class replaces (that is, overrides) the implementation in the parent class.