🔥 프로토콜의 속성 요구사항
프로토콜은 준수하는 타입에 특정 이름과 타입을 가진 인스턴스 속성이나 타입 속성을 제공하도록 요구할 수 있습니다. 프로토콜은 속성이 저장 속성인지 계산 속성인지는 지정하지 않고, 오직 요구되는 속성의 이름과 타입만을 지정하죠. 또한 각 속성이 읽기 전용(gettable)인지 혹은 읽기-쓰기(gettable and settable) 모두 가능한지도 명시합니다.
만약 프로토콜에서 읽기-쓰기 가능한 속성을 요구한다면, 상수 저장 속성이나 읽기 전용 계산 속성으로는 그 요구사항을 충족시킬 수 없습니다. 반면 프로토콜에서 읽기 전용 속성만을 요구한다면 어떤 종류의 속성으로도 그 요구사항을 만족시킬 수 있죠. 심지어 코드에서 유용하게 사용할 수 있다면 쓰기 가능한 속성으로 구현해도 무방합니다.
프로토콜에서 속성 요구사항은 항상 var
키워드를 앞에 붙여 변수 속성으로 선언됩니다. 읽기-쓰기 속성은 타입 선언 뒤에 { get set }
을, 읽기 전용 속성은 { get }
을 작성하여 표시합니다.
protocol SomeProtocol { var mustBeSettable: Int { get set } // 읽기-쓰기 속성 요구사항 var doesNotNeedToBeSettable: Int { get } // 읽기 전용 속성 요구사항 }
swift
타입 속성 요구사항을 프로토콜에서 정의할 때는 항상 static
키워드를 앞에 붙여야 합니다. 클래스에서 타입 속성 요구사항을 구현할 때는 class
나 static
키워드를 사용할 수 있지만, 프로토콜에서는 static
만 사용 가능하답니다.
protocol AnotherProtocol { static var someTypeProperty: Int { get set } // 타입 속성 요구사항 }
swift
다음은 단일 인스턴스 속성 요구사항을 가진 프로토콜의 예시입니다.
protocol FullyNamed { var fullName: String { get } // 풀 네임을 제공하는 속성 요구사항 }
swift
FullyNamed
프로토콜은 준수하는 타입에 풀 네임(full name)을 제공하도록 요구합니다. 프로토콜은 준수하는 타입의 성질에 대해서는 아무것도 지정하지 않고, 단지 그 타입이 스스로에 대한 풀 네임을 제공할 수 있어야 한다는 것만 명시하죠. 프로토콜은 String
타입의 읽기 전용 인스턴스 속성 fullName
을 가져야 한다고 선언합니다.
아래는 FullyNamed
프로토콜을 채택하고 준수하는 간단한 구조체의 예시입니다.
struct Person: FullyNamed { var fullName: String // FullyNamed 프로토콜 요구사항 충족 } let john = Person(fullName: "John Appleseed") // john.fullName은 "John Appleseed"
swift
이 예제는 특정 이름을 가진 사람을 나타내는 Person
이라는 구조체를 정의합니다. 정의부 첫 줄에서 FullyNamed
프로토콜을 채택한다고 명시하죠.
Person
의 각 인스턴스는 String
타입의 fullName
이라는 단일 저장 속성을 가지고 있습니다. 이는 FullyNamed
프로토콜의 단일 요구사항과 일치하며, Person
이 프로토콜을 올바르게 준수함을 의미합니다. (만약 프로토콜 요구사항이 충족되지 않으면 Swift는 컴파일 시점에 에러를 발생시킵니다.)
다음은 FullyNamed
프로토콜을 채택하고 준수하는 좀 더 복잡한 클래스의 예시입니다.
class Starship: FullyNamed { var prefix: String? // 선택적인 접두어 저장 속성 var name: String // 필수적인 이름 저장 속성 init(name: String, prefix: String? = nil) { self.name = name self.prefix = prefix } var fullName: String { // FullyNamed 프로토콜 요구사항 충족 return (prefix != nil ? prefix! + " " : "") + name } } var ncc1701 = Starship(name: "Enterprise", prefix: "USS") // ncc1701.fullName은 "USS Enterprise"
swift
이 클래스는 우주선을 위한 읽기 전용 계산 속성으로 fullName
속성 요구사항을 구현합니다. 각 Starship
클래스 인스턴스는 필수적인 name
과 선택적인 prefix
를 저장하죠. fullName
속성은 prefix
값이 존재하면 그 값을 사용하고, name
앞에 붙여 우주선의 풀 네임을 만듭니다.
이렇게 프로토콜의 속성 요구사항을 통해 준수하는 타입이 특정 속성을 제공하도록 강제할 수 있습니다. 이는 프로토콜에 기반한 코드를 작성할 때 매우 유용하게 사용될 수 있죠. 프로토콜과 속성의 조합으로 더욱 유연하고 추상화된 코드를 작성해 보세요!