20-1. 프로토콜 개념(Protocol)과 요구사항

🌈 devleeky16498·2022년 4월 20일
0

프로토콜은 메서드, 프로퍼티, 그리고 특정 작업이나 기능의 부분이 적합한 다른 요구사항의 청사진을 정의한다. 해당 요구사항 구현을 위해 프로토콜은 클래스, 구조체, 열거형에 의해서 채택될 수 있다. 그리고 이 요구사항을 충족하는 모든 타입은 프로토콜을 준수한다고 말한다.

프로토콜 구문

  1. 클래스, 구조체, 열거형과 유사하게 프로토콜을 정의한다.
protocol SomeProtocol {
	//프로토콜 내용 입력
}

struct SomeStructure : FirstProtocol, AnotherProtocol {
	//구조체 정의 입력
}
//사용자 정의 타입은 콜론으로 구분된 타입 이름뒤에 프로토콜의 이름을 위치시켜 준수할 프로토콜을 채택한다.

class SomeClass : SomeSuperClass, FirstProtocol, SecondProtocol {
	//클래스 정의 입력
}

//클래스가 상위 클래스를 상속하는 경우 채택한 모든 프로토콜 전에 상위 클래스 이름을 위치시킨다

프로퍼티 요구사항 (property requirements)

  1. 프로퍼티는 특정 이름과 타입을 가진 인스턴스 프로퍼티 또는 타입 프로퍼티를 제공하기 위해서 모든 준수하는 타입을 요구할 수 있다. 이 때 요구된 프로퍼티의 이름과 타입만 지정하며 해당 프로퍼티가 저장된 프로퍼티 또는 계산된 프로퍼티 인지에 대한 것은 지정하지 않는다. 또한 각 프로퍼티가 읽기 전용인지 아닌지에 대해서도 지정해줘야 한다. 프로퍼티 요구사항은 항상 var키워드와 함께 변수 프로퍼티로 선언된다. gettable과 settable프로퍼티는 타입 선언 후 { get set }으로 나타내고 gettable 프로퍼티는{ get }으로 작성해서 나타낸다.
protocol SomeProtocol {
	var mustBeSettable : Int {get set}
    var doesNotNeedToBeSettable : Int {get}
}

protocol AnotherProtocol {
	static var someTypeProperty : Int { get set }
}
//다음과 같은 경우 타입 프로퍼티를 프로토콜 요구사항으로 가지는 경우이다.

메서드 요구사항(method requirements)

  1. 프로토콜은 준수하는 타입에 의해 구현되기 위해 지정한 인스턴스 메서드와 타입 메서드를 요구할 수 있다. 일반적 메서드와 같은 규칙으로 가변 파라미터는 허용된다. 그러나 기본 값은 프로토콜 정의내에서 매서드 파라미터에 대해 지정될 수 없다. 타입 메서드는 앞에 static 키워드를 접두사로 붙여서 구현해준다.
protocol : SomeProtocol {
	static func someTypeMethod()
}
//위 프로토콜은 타입 메서드 준수를 요구한다.

protocol RandomNumberGeterator {
	func random() -> Double
}
//단일 인스턴스 메서드 요구사항을 가지는 프로토콜 또한 정의한 상태이다.

class LinearCongrautiaGenerator : RandomNumberGenerator {
	var lastRandom = 42.0
    let m = 139968.0
    let a = 3877.0
    let c = 29830.0
    
    func random() -> Double {
    	lastRandom = ((lastRandom * a + c)
        return lastRandom / m
    }
}
//다음의 클래스는 두번째 프로토콜을 준수하고 해당 인스턴스 메서드를 구현해주어 잘 준수된 상태이다.
  1. 메서드가 속한 인스턴스를 수정 또는 변경해야 하는 경우가 있다.값 타입에 대한 인스턴스 메서드의 경우 func 앖에 mutating키워드를 위치시켜 메서드가 속한 인스턴스의 프로퍼티를 수정할 수 있음을 나타내준다.프로토콜도 마찬가지이며 이를 통해서 구조체와 열거형이 프로토콜을 채택하고 메서드 요구사항을 충족할 수 있다.
protocol Toggleable {
	mutating func toggle()
}
//구조체나 열거형에 대해 Togglable 프로토콜을 구현하면 해당 구조체 또는 열거형은 
//mutating으로 펴시된 toggle() 메서드 구현을 제공하는 프로토콜 준수가 가능하다.

enum OnOffSwitch : Togglable {
	case off, on
    mutating func toggle() {
    	switch self {
        case .off:
        	self = .on
        case .on:
        	self = .off
        }
    }
}

var lightSwitch = OnOffSwitch.off
lightSwitch.toggle()
// 이젠 해당 값이 .on으로 변경되었다.

초기화 구문 요구사항

  1. 프로토콜은 준수하는 타입에 의해 지정된 초기화 구문을 요구할 수 있다.
protocol SomeProtocol {
	init(someParameter : Int)
}
  1. 지정된 초기화 구문 또는 편의 초기화 구문으로 준수하는 클래스에 프로토콜 초기화 구문 요구사항 구현이 가능하다. 이 때는 required키워드와 함께 구분을 짓는다.
class SomeClass : SomeProtocol {
	required init(someParameter : Int) {
    	//프로토콜 초기화 정의
    }
}

//다음 required수식어를 사용할 경우 준수하는 클래스의 모든 하위 클래스도 해당 프로토콜의 초기화를 구현해야 한다.
//final클래스는 하위클래스가 없으므로 final로 표시된 클래스에는 required 수식어를 프로토콜 초기화 구문 구현에 표시할 필요가 없다. 
  1. 하위 클래스가 상위 클래스의 지정된 초기화 구문을 재정의 하고 프로토콜로부터 일치하는 초기화 구문 요구사항이 구현되면 required와 override수식어 둘다 초기화 구문에 표시한다.
protocol SomeProtocol {
	init()
}

class SomeSuperClass {
	init() {
    //
    }
}

class SomeSubClass : SomeSuperClass, SomeProtocol {
	//"required" from protocol, "override" from superclass
    required override init() {
    	//생성자를 정의해준다
    }
}
//다음과 같이 하위클래스에서 프로토콜에서 요구되는 생성자와 함께 수퍼클래스의 생성자를 재정의할때는 키워드를 위와같이 작성해준다.
profile
Welcome to Growing iOS developer's Blog! Enjoy!🔥

0개의 댓글