-
Swift - Protocol Optional RequirementProgramming/Swift 2022. 1. 4. 19:55
안녕하세요! BeePeach입니다 :)
오늘 다뤄볼 내용은 Protocol Optional Requirement(선택적 요구사항)입니다.
먼저 헷갈릴 수 있는 단어를 확실하게 하고 가겠습니다.
Optional requirement에서의 Optional은 우리가 이전에 공부한 Optional Type을 의미하는 게 아닙니다.
여기서 Optional은 단어 그대로 선택적이라는 형용사적 의미이고 우리가 이전에 Int?과 같이 사용하던 Optional은 형용사적 의미가 아니라 Optional Type을 지칭하는 명사적 의미입니다.
지금까지 공부한 protocol은 requirement(요구사항)를 선언하고 Type이 protocol을 채용한다면 반드시 요구사항을 구현해야 했습니다.
선택적 요구사항이란 Type이 protocol을 채용하더라도 해당 멤버(property, method, subscript)는 채용하지 않아도 되는 요구사항을 의미합니다.
그럼 어떻게 정의하고 사용하는지 공부해보도록 하겠습니다.
Syntax
핵심은 @objc 특성과 optional 키워드를 추가하는 것입니다.
@objc는 이름에서 유추할 수 있듯 Objective-C에서 사용 가능하도록 만들어주는 특성입니다.
우리는 Swift에서 사용할 거고 Objective-C에서 사용하고 싶은 마음은 하나도 없어도 Optional Requirement를 구현하기 위해서는 꼭 이 특성을 추가시켜줘야 합니다.
먼저 protocol 앞에 @objc 특성을 추가시킨 다음
그 이후 optional requirement로 만들고 싶은 멤버 앞에 @objc 특성과 optional 키워드를 작성해줘야 합니다.
이중에 하나라도 빼먹는다면 컴파일 에러가 발생하므로 빼먹을 일은 없을 거예요.
요구사항에 init은 보이지 않습니다. init은 선택적 요구사항으로 만들 수 없습니다.
프로퍼티, 메서드, 서브 스크립트만 가능합니다.
헷갈리면 안 되는 부분은 선택적(optional) 요구사항이니까 있을 수도 있고 없을 수도 있으면 Type을 옵셔널로 해야 하는 거 아니야???라고 생각할 수 있습니다.
하지만 문법을 보면 프로퍼티나 메서드의 타입을 Optional Type으로 선언하지 않았습니다.
그냥 일반 Type으로 정의를 했죠??
하지만 protocol Type으로 인스턴스를 만들고 해당 멤버를 사용할 때 자동적으로 Optional type이 되는 것을 확인할 수 있습니다.
이 부분은 아래에서 확인해 보겠습니다.
Class에서만 사용 가능
@objc 특성을 사용하기 때문에 선택적 요구사항은 class에서만 사용이 가능합니다.
Struct, Enum에서 사용할 수 없습니다.
예제
Person 프로토콜을 만들었습니다.
name 프로퍼티는 필수 요구사항이고 job프로퍼티와 work() 메서드는 선택적 요구사항입니다.
Person을 채용하면 job, work()는 구현하고 싶으면 하고 안 하고 싶다면 안 해도 됩니다.
Employed와 Jobless는 모두 Person을 채용하고 있습니다.
Employed에서는 요구사항을 모두 구현하고 Jobless는 직업이 없어서 job과 work() 메서드를 구현 안했습니다ㅠㅠ
프로토콜에 요구사항으로 선언되어있는데 job프로퍼티와 work() 메서드를 꼭 구현하지 않아도 에러가 나지 않는 것을 확인할 수 있습니다.
그리고 앞에서 설명했듯이 선택적 요구사항이라고 해서 해당 요구사항들을 optional type으로 선언해야 하는 것은 아닙니다.
구현 코드를 보면 optiona type으로 선언하지 않은 것을 확인할 수 있습니다.
Employed와 Jobless 인스턴스를 생성했습니다.
employed로 job 프로퍼티에 접근해보고 work() 메서드를 호출했습니다.
아무 문제없죠??
unemployed로 job과 work() 메서드에 접근하면 class 선언부에 해당 멤버들이 없으니 에러가 나는 것은 당연합니다.
주의 사항
그런데 잘 생각해보면 아까 설명에서 'protocol Type으로 인스턴스를 만들고 해당 멤버를 사용할 때 자동적으로 Optional type이 되는 것을 확인할 수 있습니다.'라고 설명을 했었습니다.
사용할 때 optional type으로 된다고 했는데 결과를 보면 전혀 optional type이 아닙니다.
이게 헷갈리는 부분인데 위 설명을 다시 잘 보세요!
'protocol Type으로 인스턴스를 만들고' <-- class Type의 인스턴스를 만든 게 아니라 protocol로 인스턴스를 만들 때입니다.
Class인 Jobless, Employed의 인스턴스가 아니라 protocol인 Person의 인스턴스를 만들었습니다.
이 변수에는 Person 프로토콜을 채용한 Type을 가진 값은 뭐든 할당 가능하죠??
그래서 이전에 생성했던 employed를 할당했습니다.
그러고 아까처럼 job프로퍼티에 접근해보니 optional type으로 나오는 것을 확인할 수 있습니다.
work() 메서드도 사용하려고 하니 work?()로 optional chaining을 사용해야 합니다.
메서드를 이렇게 접근해야 하는 이유는 work() 메서드의 타입 자체가 Optional이기 때문입니다.
예를 들어서 (Int) -> String 타입의 메서드가 있었다면 선택적 요구사항으로 구현된 메서드의 타입은 ((Int) -> String)?이 됩니다.
메서드의 리턴 값이 optional이 되는 게 아니라 자체가 optional이 된다는 것을 꼭 헷갈리면 안 됩니다.
그리고 이번엔 person 변수에 unemployed를 할당해봤습니다.
그럼 umemployed는 Person 프로토콜을 채용하지만 선택적 요구사항인 job과 work()는 구현하지 않았기 때문에 nil이 나오는 것을 확인할 수 있습니다.
참고자료
https://docs.swift.org/swift-book/LanguageGuide/Protocols.html
Protocols — The Swift Programming Language (Swift 5.6)
Protocols A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of tho
docs.swift.org
728x90'Programming > Swift' 카테고리의 다른 글
Swift - Equatable Protocol (0) 2022.01.14 Swift - Protocol Extension (0) 2022.01.12 Swift - Protocol Composition (0) 2022.01.03 Swift - Protocol Inheritance (0) 2022.01.02 Swift - Protocol as Type (0) 2021.12.29