프로토콜 (Protocol)
- 클래스, 구조체 또는 열거형과 같은 타입이 따라야 할 요구사항을 정의하는 일종의 추상 청사진
- 인터페이스와 유사하게 작동하며, 객체들 사이의 통신과 상호 작용을 위한 규칙 제공
- 클래스, 구조체, 열거형은 프로토콜을 채택(Adopt)하여 해당 프로토콜이 요구하는 속성과 메서드를 구현
1. 프로토콜 선언
import UIKit
// 프로토콜은 약속
// 이름 설정은 **delegate, **able, **ing 등으로 설정
protocol Naming {
// 우리는 이런 변수와 메서드를 가지고 있을 것입니다. 라고 약속하는 것
var name : String { get set}
func getName() -> String
}
- 'Naming' 프로토콜은 'name' 프로퍼티와 'getName' 메서드를 요구사항으로 가지고 있음
- 프로토콜 내 요구사항은 중괄호 '{ }' 가 없이 정의 됨
- 프로퍼티에서 'get' 또는 'get set' 은 무조건 설정해야 함
2. 프로토콜 채택, 준수(Implement)
struct Friend : Naming {
var name: String
func getName() -> String {
"제 친구 이름은 \(self.name)"
}
}
- 'Friend' 구조체에서는 'Naming' 프로토콜을 채택함
- 따라서 'Naming' 프로토콜의 'name', 'getName()' 을 반드시 구현해야 함
3. 프로토콜 준수한 구조체 사용
var myFriend = Friend(name: "홍길동")
print(myFriend.getName())
프로토콜 상속
- 하나 이상의 프로토콜을 다른 프로토콜에게 상속하는 개념
- 기존의 프로토콜을 기반으로 새로운 프로토콜을 정의하고, 기존 프로토콜에 정의된 요구사항들을 재사용
1. 프로토콜 정의
import UIKit
// 프로토콜은 약속
// 이름 설정은 **delegate, **able, **ing 등으로 설정
protocol Naming {
// 우리는 이런 변수와 메서드를 가지고 있을 것입니다. 라고 약속하는 것
var name : String { get set}
func getName() -> String
}
protocol Aging {
var age : Int { get set}
}
protocol UserInformation : Naming, Aging{
}
- 'UserInformation' 프로토콜 : 'Naming', 'Aging' 프로토콜을 상속
2. 프로토콜 구현
class MyBestFriend : UserInformation{
var name: String = "홍길동"
func getName() -> String {
"나의 bestFreind는 \(self.name)"
}
var age: Int = 22
}
- 'UserInformation' 프로토콜을 채택한 'MyBestFreind' 클래스 정의
- 'MyBestFreind' 는 'UserInformation' 프로토콜을 채택했기 때문에 해당 프로토콜에서 요구하는 'name', 'age', 'getName()' 메서드를 모두 구현해야 함
프로토콜 확장(Protocol Extension)
- 이미 정의된 프로토콜에 새로운 기능을 추가하거나 기존의 요구사항을 구현하도록 도움
- 프로토콜을 채택한 모든 타입에 대해 기본 구현을 제공 가능
기본 Protocol
protocol Naming {
var name : String { get set}
func getName() -> String
}
기능 1. 프로토콜에 기본 구현 제공
Protocol 확장 (기본 구현)
extension Naming{
func getName() -> String {
return "제 이름은 \(self.name)입니다."
}
}
struct Person : Naming{
var name: String
}
var person = Person(name: "홍길동")
print(person.getName()) // 출력 : 제 이름은 홍길동 입니다.
- 'extenstion' 을 통해 'Naming' protocol을 확장함으로써 'getName()' 메서드를 기본 구현 제공
- 'Naming' 프로토콜을 채택한 'Person' 구조체는 별도의 'getName()' 메서드를 구현하지 않아도 기본 구현이 사용 됨
기능 2. 프로토콜에 새로운 기능 추가
// 프로토콜 확장 (새로운 기능 추가)
extension Naming{
func address() -> String{
return "저는 경기도에 살고 있습니다."
}
}
struct Person : Naming{
var name: String
}
var person = Person(name: "홍길동")
print(person.address()) // 저는 경기도에 살고 있습니다.
- 'Naming' 프로토콜에 'address()' 라는 새로운 메서드 추가
- 'Person' 구조체가 'Naming' 프로토콜을 채택하여 'address()' 메서드 사용 가능
프로토콜 확장은 기존의 프로토콜을 수정하지 않고도 기능을 추가하거나 기본 구현을 제공할 수 있음
이를 통해 프로토콜과 타입들 사이의 강력한 결합도를 유지하면서도 코드 재사용성과 유지 보수성을 향상 시킬 수 있음
참고)
https://www.youtube.com/watch?v=ZBqbuQzmN4o
https://www.youtube.com/watch?v=an1vLvTDIKw
https://www.youtube.com/watch?v=D-zrCL7q-Eg
'Swift' 카테고리의 다른 글
Swift - UserDefaults (0) | 2023.08.16 |
---|---|
Swift - 키보드 올라옴 감지(NotificationCenter, Observer 사용) (0) | 2023.08.11 |
Swift 사진 설정하기 (UIImagePickerController 사용) (0) | 2023.08.05 |
Swift - UIKit, SnapKit 비교 (0) | 2023.07.23 |
Swift - PickerView (0) | 2023.07.19 |