일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- IOS
- 계명대
- 자료구조
- 자바스크립트 자료구조
- SWIFT
- 자바스크립트
- queue
- 이종호
- 자스민
- 호키도키
- hokidoki
- 스위프트
- HTML
- data structure
- javascript
- Hitit
- hokeys
- 계명대 이종호
- 리액트
- Svelte
- 비동기
- 힛잇
- 개발자
- 호키스
- TDD
- react
- 스벨트
- jest
- 리액트 예제
- 개발
- Today
- Total
Dog foot print
[SWIFT] protocol 본문
Protocol
애플의 진영에서는 인터페이스
라는 것이 존재하지 않고, 프로토콜
이라는 것이 존재한다. 어찌 보면 규약이라는 개념은 비슷하지만 그 규칙의 강제성이나, 제한은 인터페이스가 훨씬 높다. 즉 프로토콜이라는 개념은 최소한의 만족할 만한 규칙
이며, 인터페이스는 부가적인 것이 존재하지 않는 규칙
으로 정리 할 수 있다.
프로토콜은 명세라고 불리우기도 하는데, 이는 특정한 것을 만들기 위한 설계서
와 같은 역할을 한다. 이 프로토콜이라는 규칙을 준수하며 객체나 구조체, 열거형을 만드는 것을 프로토콜을 구현한다
라고 표현 한다.
프로토콜의 구현
protocol [프로토콜 명]{
프로토콜 명세 ...
}
class A : [protocol] {
}
extension A : [protocol] {
}
enum B : [protocol] {
}
struct C : [protocol] {
}
프토토콜을 구현 할 수 있는 타입은 열거형
, 구조체
, 클래스
, 익스텐션
입니다.
프로토콜에서 프로퍼티 명세하기
protocol SomeProtocol {
<변수타입> <변수명> : <변수타입> { get set}
<변수타입> <변수명> : <변수타입> { get }
}
protocol SomeProtocol {
var name : String {get set}
var age : String {get}
}
class A : SomeProtocol {
var name : String = "";
var age : Int = {
return 19;
}
}
프로토콜에서 프로퍼티를 명세 할 때, 구현 부분이 아니기 때문에 특정 값을 명시하지 않습니다. 할당연산자가 존재하지 않고, { get , set} 의 형태를 띄고 있는데, 이는 프로퍼티가 읽기와 쓰기
속성이 가능한지를 명세하는 부분 입니다.
Note : 읽기와 쓰기 혹은 읽기 만 가능합니다.
프로토콜에서 메서드 명세하기
protocol SomeProtocol {
func (매개변수 : 타입) -> 반환 타입
func (매개변수 : 타입) // Void 반환;
}
protocol SomeProtocol {
func foo()
func add(x : Int, y : Int) -> Int
}
프로토콜에서 메서드를 명세 할 때는 함수의 식별자
를 명세해주면 됩니다. 즉 메서드명
, 파라메터
, 반환타입
을 명세하면 됩니다.
프로토콜에서 Static과 mutating 사용하기
protocol SomeProtocol {
var counters : Int {get set}
static func foo()
mutating func addCounter(x : Int) -> Int
}
struct Counter : SomeProtocol {
var counters : Int = 0;
static func foo(){
print("hello world")
}
mutating func addCounter(x : Int ) -> Int{
self.counters += x
return self.counters
}
}
구조체에서 메서드를 이용하여, 내부 변수의 재할당이 일어날 때는 함수 키워드 앞에 mutating
을 작성해주어야 합니다. 프로토콜을 명세할 때 또한 동일하게 mutating을 작성해주어야 하며, 만약 명세 해주지 않고 구조체 구현에서 mutating을 작성하게 되면 명세를 지키지 않음으로 간주하고 에러를 발생 시킵니다.
Note : 만약 mutating이 명시된 프로토콜을 구조체가 아닌 클래스에서 이를 구현하게 된다면 class에서는 mutating을 따로 구현할 필요가 없으니 안심해도 됩니다.
protocol과 초기화 메서드
import UIKit
protocol CounterProtocol {
var counts :Int {get set}
init()
init(c : Int)
}
class Counter : CounterProtocol{
internal var counts: Int;
required init(){
self.counts = 0;
}
required init(c : Int){
self.counts = c;
}
}
let c = Counter(c: 10);
c.counts
초기화 구문을 명세 할 때는 init
과 생성자 인자
만 명시하면 됩니다. 다만 구현하는 부분에서는 프로토콜에서 명세한 init을 구현한다는 것을 알리기 위해 required
를 init 앞에 명시해주어야 합니다.
만약 자식 클래스에서 특정 프로토콜을 구현하며 이미 부모에서 구현된 init
이 존재한다면 override
구문과 required
구문을 함께 명시해야합니다.
import UIKit
protocol SomeProtocol {
var count : Int {get set}
init()
init(c : Int)
}
class A {
init(){
}
}
class B : A , SomeProtocol{
var count: Int = 0;
override required init(){
super.init()
}
required init(c : Int){
self.count = c;
}
}
Note : 만약 init이 명세 되어 있는 프로토콜을 구조체가 구현한다고 하면 멤버와이즈 초기화 구문이 존재해도 명시된 init
을 구현 해야합니다.
Type 으로써의 Protocol
import UIKit
protocol SomeProtocol {
func foo()
func boo()
}
class A : SomeProtocol {
func foo(){
print("foo!");
}
func boo(){
print("boo!")
}
func coo(){
print("coo!")
}
}
let a : A = A();
a.boo()
a.foo()
a.coo()
let c : SomeProtocol = A();
c.boo()
c.foo()
//c.coo() // 존재하지 않음
만약 프로토콜을 구현한 클래스에서 프로토콜 명세보다 더 많은 멤버를 가지고 있어도 프로토콜의 명세를 구현했기 때문에 에러를 발생 시키지 않습니다. 그러나, 더 많은 기능을 가지고 있는 클래스의 인스턴스를 프로토콜 타입의 변수에 할당 한다면 이 인스턴스는 많은 기능을 실제로 가지고 있더라도, 프로토콜 명세 이외의 멤버에는 접근 할 수가 없습니다.
만약 클래스를 정의할 때 2개 이상의 프로토콜을 구현 하였다면 다음과 같이 &
을 사용하여 새로운 타입을 만들어 사용 할 수 있습니다.
import UIKit
protocol SomeProtocol {
func foo()
func boo()
}
protocol SomeProtocol2{
func coo()
}
class A : SomeProtocol, SomeProtocol2 {
func foo(){
print("foo!");
}
func boo(){
print("boo!")
}
func coo(){
print("coo!")
}
}
let a : A = A();
a.boo()
a.foo()
a.coo()
let c : SomeProtocol & SomeProtocol2 = A();
c.boo()
c.foo()
c.coo()
'IOS > Swift' 카테고리의 다른 글
[IOS] 쓰레드와 동시작업 (0) | 2021.09.22 |
---|---|
[Swift] 동기적 작업과 비동기적 작업 (0) | 2021.09.20 |
[SWIFT] enumeration (0) | 2021.07.21 |
[SWIFT] 초기화 (0) | 2021.07.20 |
[SWIFT] Type casting (0) | 2021.07.20 |