프로토콜

조현우·2022년 7월 12일
0

상속의 한계

상속은 클래스에서만 가능하며 필요하지않은 속성과 메서드까지 모두 하위 클래스에서 상속받아야 하는 단점이 있다. 이러한 문제들은 프로토콜(Protocols)을 사용해 기능을 대체할 수 있다.

프로토콜이란?

프로토콜은 영어로 '규약'의 뜻을 갖고 있다.
프로토콜은 클래스, 구조체, 열거형에서 사용가능하며 여러개의 프로토콜을 각 타입에 적용 가능하다. 즉 스위프트는 프로토콜을 "일급객체"로 취급하고 있다. 따라서,

  • 타입으로서 변수에 할당할 수 있다.
  • 함수를 호출할때, 프로토콜을 파라미터로 전달할 수 있다.
  • 함수에서 "프로토콜"을 반환할 수 있다.

프로토콜 기본 문법

  • 클래스, 구조체, 열거형 에서 모두 사용 가능.
  • 클래스의 경우 상위 클래스를 먼저 선언 후, 프로토콜을 채택해야 햔다.
    protocol MyProtocol {	// 최소한의 요구사항 나열
    	func doSomething() -> Int
    }
    
    class FamilyClass { }
    
    class MyClass: FamilyClass, MyProtocol {
    	...
        func doSomething() -> Int {
        	...
        }
    }
    
    struct MyStruct: MyProtocol {
    	...
        func doSomething() -> Int {
        	...
        }
    }
    
    enum MyEnum: MyProtocol {
    	...
        func doSomething() -> Int {
        	...
        }
    }

프로토콜의 요구사항 정의하는 방법

속성 요구사항 정의

인스턴스 속성 요구사항

protocol MyProtocol {
	var id: String { get }	// 항상 'var'로만 선언해야한다.
    var name: String { get set }
    static var type: String { get set }
    mutating func toggle() // 
}

{ get } 은 구현부에서

  • 저장 속성 : let / var
  • 계산 속성 : 읽기(get) / 읽기쓰기(get/set)

{ get set } 은 구현부에서

  • 저장 속성 : var
  • 계산 속성 : 읽기쓰기(get/set)

타입(static) 속성 요구사항

  • 최소한의 요구사항을 지정.
  • 저장 타입 속성 / 계산 타입 속성으로 모두 구현 가능(프로토콜의 요구사항만으로는 저장 / 계산 속성의 구별 불가).
  • 채택시 저장 타입 속성에서 static 키워드로만 구현 가능(저장 속성 재정의 불가 원칙).
  • 클래스에서 채택시 계산 타입 속성에서 static / class 키워드로 모두 구현 가능(타입 속성의 의미를 갖는다). class 키워드는 재정의 가능하다.

메서드 요구사항

  • 메서드의 헤드부분(인풋/아웃풋)을 정의.
    예) func random() -> int
  • mutating 키워드: 구조체에서 저장 속성을 변경하는 경우, 구조체도 채택 가능하도록 허락하는 키워드. 해당 키워드를 사용하더라도 클래스에서도 사용할 수 있음.
  • 타입 메서드 : 클래스에서 채택시 static / class 키워드로 모두 구현 가능.(타입 메서드의 의미) (class 키워드는 재정의 가능)

생성자 요구사항

  • 생성자를 요구사항으로 지정 가능.
  • 클래스에서 생성자 채택시, required를 붙여야 함.
  • 클래스가 final로 선언되면 required 생략 가능.
  • 클래스에서는 반드시 지정생성자로 구현할 필요없음.(편의생성자로 구현도 가능)

서브스크립트 요구사항

  • get은 필수로 구현해야 한다.
  • set의 구현은 선택사항이다.

{ get } 은 읽기(get) / 읽기쓰기(get/set) 모두 구현 가능하다.

{ get set } 은 읽기쓰기(get/set)를 모두 구현해야 한다.

중요!!

확장에서 구현한 메서드는 하위 클래스에서 재정의 할 수 없다는 단점이 있으나, 관습적으로 프로토콜확장(extension)에서 구현하는 것을 권장한다.

profile
현우

0개의 댓글