Swift #14 - 프로토콜, extension
1. 프로토콜
- 인터페이스와 구현
#인터페이스(interface)
#구현(implementation)
#클래스 : 인터페이스 + 구현
#프로토콜 : 인터페이스 Only
*구현이 없어서 단독 사용 불가
*클래스, 구조체와 함께 사용
*메소드, 프로퍼티 구현 약속
- 프로토콜 정의와 채택
*프로토콜 정의
protocol PROTOCOL_NAME {
}
*채택
class CLASS_NAME : PROTOCOL_NAME {
}
|
cs |
#클래스와 프로토콜
*상속과 프로토콜 : 부모 클래스를 첫 번째, 프로토콜은 두 번째부터
- 프로토콜 사용 예제
*프로토콜 정의
protocol Singing {
func sing()
}
*클래스 채택
class Bird : Singing {
func sing() {
print("짹짹짹")
}
}
*객체 생성과 사용
var sparrow = Bird()
sparrow.sing()
|
cs |
#같은 인터페이스, 다양한 구현
*클래스, 구조체, enum에 채택
class Bird : Singing {
func sing() {
print("짹짹짹~")
}
}
struct Cat : Singing {
func sing() {
print("갸르릉 갸르릉")
}
}
|
cs |
- 다중 프로토콜 채택
protocol Dancing {
func dance()
}
class Human : Dancing, Singing {
func sing() {
print("랄랄라~")
}
func dance() {
print("춤추기")
}
}
*프로토콜 내 타입 메소드 선언
product Species {
static func species() -> String
}
|
cs |
- 프로토콜 상속
*프로토콜 상속과 구현
protocol Singing {
func sing() {}
}
protocol Dancing {
func dance() {}
}
protocol Entertaining : Singing, Dancing {
}
*프로토콜 상속 관계까지 고려해서 구현
struct Human : Entertaining
func sing() {}
func dance() {}
}
|
cs |
- 프로토콜 내 프로퍼티
#프로토콜 내 프로퍼티 선언
*get/set 행위만 선언
*get 전용, get/set 모두
*set 전용은 없음
protocol HoldingBreath {
var duration : Int { get set }
}
*타입 프로퍼티 선언 가능
|
cs |
#프로토콜의 프로퍼티 구현
*저장 프로퍼티로 구현
struct MyStruct : HoldingBreath {
var duration : Int
}
*계산 프로퍼티 구현
class MyClass : HoldingBreath {
var duration : Int {
get {
return 0
}
set {}
}
}
|
cs |
- 프로토콜 내 Initializer
#프로토콜 내 Initializer 선언
protocol Named {
init(name : String)
}
|
cs |
#구현하기
*클래스 구현 시 required 추가
class Monster : Named {
required init(name: String) {
self.name = name
}
}
*convenience initializer에도 required 추가
*struct에는 required 사용 안 함
struct Boss : Named {
init(name : String) {}
}
|
cs |
- 프로토콜 내 Failable Initializer
*프로토콜 선언
protocol Named {
init?(name : String)
}
*Non-failable Initializer로 구현하기
class Monster : Named {
required init(name : String) {}
}
*Failable Initializer로 구현하기
struct Boss : Named {
init?(name : String) {}
}
|
cs |
- 프로토콜 타입
#프로토콜을 타입으로 사용
*프로토콜을 타입으로 선언
*프로토콜 내 메소드, 프로퍼티만 사용 가능
var singingAnimal : Singing = Human()
singingAnimal.sing()
*다수의 프로토콜 타입
func entertain(who : Singing & Dancing) {
}
|
cs |
- 클래스 전용 프로토콜
#클래스에서만 채택 가능
*class 키워드 사용
protocol MyProtocol : class {
}
*구조체, enum에서는 에러
*클래스에서만 채택, 구현 가능
*프로토콜 타입을 weak와 사용할 때
class MyClass : MyProtocol {
weak var property : MyProtocol!
}
|
cs |
2. extension
- extension
*타입을 나눠서 작성
*하나의 타입으로 동작
*기존에 작성된 타입(혹은 남이 작성한) 확장
*서로 다른 파일에 작성 가능
class Dog {
func eat() { print("밥 먹기") }
}
extension Dog {
func bike() { print("멍멍멍") }
}
var myDog = Dog()
myDog.eat()
myDog.bike()
|
cs |
#extension으로 가능한 것
*계산 프로퍼티
*메소드
*프로토콜
*서브스크립트
*nested type
#extension으로 불가능한 것
*designated initializer
*저장 프로퍼티
- 프로퍼티
#extension과 프로퍼티
extension Dog {
//저장 프로퍼티 에러
//계산 프로퍼티
var everageLife : Int! {return 15}
|
cs |
- Initializer
#Initializer 추가
*Designated Initializer 추가 불가
*Convenience Initializer 추가
class Dog {
// Designated Initializer
init() {}
}
extension Dog {
convenience init(name : String) {
self.init()
}
}
|
cs |
- 프로토콜
#프로토콜 채택 및 구현
*extension내 프로토콜 채택 구현
*프로토콜에는 Initializer가 없을 것
protocol Running {
func run()
}
extension Dog : Runnig {
func run() {
print("뛰기")
}
}
|
cs |
3. 프로토콜 extension
- 프로토콜
#프로토콜 extension
*프로토콜 extension에 구현 코드 작성 가능
*프로토콜 채택으로 프로토콜 extension의 구현 코드 사용
*다중 상속과 비슷한 효과
*구조체/Enum 사용 시 중복 코드 문제 해결
#POP
*POP(Protocol Oriented Programming)
*구조체와 Protocol, extension 활용한 프로그래밍 기법
- 프로토콜 extension
#프로토콜과 프로토콜 확장
*프로토콜과 프로토콜 확장
protocol Movable { }
extension Movable {
func move() {
print("Go! go! go!")
}
}
*프로토콜 채택, 객체를 이용한 호출
struct Human : Movable {}
var man = Human()
man.movel()
|
cs |
#다중 프로토콜 채택
*다중 상속 효과
*기본 구현 재정의
class Superman : Movable, Flyable {
func move() {
print("Move Fast")
}
}
var superaman = Superman()
superman.move()
superman.fly()
|
cs |
- 구조체와 프로토콜 Extension
#상속이 없는 구조체
*코드 중복이 발생하는 상황
struct Bird {
func move() {
print("이동하다")
}
func fly() {
print("날다")
}
}
struct Airplane {
func move() {
print("이동하다")
}
func fly() {
print("날다")
}
}
|
cs |
#프로토콜 extension으로 코드 중복 제거
protocol Movable {}
extension Movable {
func move() {
print("이동하다")
}
}
protocol Flyable {}
extension Flyable {
func fly() {
print("날다")
}
}
struct Bird : Movable, Flyable {
}
struct Airplane: Movable, Flyable {
}
|
cs |