// 프로토콜에서 생성자를 선언하고 형식에서 요구사항을 만족해보자
// {} , body 생략
// failable로 선언하는 것도 가능
protocol Figure {
var name: String { get }
init(n: String)
}
struct Rectangle: Figure {
// 구조체에는 속성만 선언되어 있는데 지금도 요구사항을 만족하고 있다.
// 왜냐? 기본적으로 생성되는 init이 프로토콜에 선언된 init과 동일하기 때문에
// 프로토콜에 있는 생성자 파라미터의 이름을 바꾸면 직접 구현해야함
var name: String
init(n: String) {
name = n
}
}
class Circle: Figure {
var name: String
// class에서는 상속을 고려해야하고 모든 서브클래스에서 프로토콜의 요구사항을 만족시켜야 하기 때문에 required init으로 선언해야 한다.
required init(n: String) {
name = n
}
}
// final 키워드를 붙이면 이 클래슨는 상속할 수 없는 클래스이기 때문에 required 키워드를 붙이지 않아도 만족한다.
final class Triangle: Figure {
var name: String
init(n: String) {
name = n
}
}
// Figure, Circle 클래스를 두개 같이 상속받는건 중복되기 때문에 불가능함
class Oval: Circle {
var prop: Int
init() {
prop = 0
super.init(n: "Oval")
}
// convenience 키워드로 init을 생성해도 요구사항을 만족한다.
required convenience init(n: String) {
self.init()
}
}
protocol Grayscale {
init(white: Double)
}
struct Color: Grayscale {
// Nonfailable init을 failable init으로 구현했기 때문에 요구사항 만족 x
// init?(white: Double) {
//
// }
// !를 붙이면 요구사항 만족시키지만 초기화에 실패하면 crush가 발생한다.
init!(white: Double) {
<#code#>
}
// 프로토콜이 init? -> failable init으로 구현되어 있으면
// init? init! init 세개다 요구사항 만족
}