[Swift] Day11 - Protocols and extensions

한철희·2023년 3월 2일
0

100 DaysOfSwift

목록 보기
7/11

으어 오늘부터 다시 학교네요
벌써 달성률이 10프로는 됐네요
11일차도 힘차게 해봅시다


Protocols

프로토콜은 특정 기능 수행에 필요한 필수적인 요소들을 정의한 것입니다
프로토콜을 만족시키는 타입을 프로토콜을 따른다(conform)라고 합니다

먼저 Identifiable프로토콜을 생성하고 시작하죠
정의 방법은 구조체, 클래스와 유사합니다

protocol Identifiable {
    var id: String { get set }
}

getset을 통해 읽고 쓰기의 가능함을 정할 수 있습니다

struct User: Identifiable {
    var id: String
}

프로토콜은 요구사항을 작성해 놓은 것이기에 따로 인스턴스를 생성할 수는없습니다. 하지만 프로토콜을 만족하는 구조체는 작성할 수 있죠

func displayID(thing: Identifiable) {
    print("My ID is \(thing.id)")
}

이렇게 displayID()함수르 작성하면 Identifiable한 개체들을 수용할 수 있게 됩니다.

문법이 익숙하지 않아서 그런지 조금 난해하네요


Protocol inheritance

프로토콜은 다른 프로토콜로부터 상속받을 수도 있습니다.
클래스와는 다르게 상속을 여러개 받을수 있습니다.

확인을 위해 프로토콜을 3개 만들어보죠

protocol Payable {
    func calculateWages() -> Int
}

protocol NeedsTraining {
    func study()
}

protocol HasVacation {
    func takeVacation(days: Int)
}

이제 Employee 프로토콜을 만들건데요
위의 3프로토콜을 전부 상속받을 겁니다.
따로 추가할 내용은 없으므로 {}는 빈 상태로 둡니다

protocol Employee: Payable, NeedsTraining, HasVacation { }

상속을 여러개 받을 때는 ,로 구분해주면 됩니다.


Extensions

확장(extension)은 타입에 메서드를 추가해서 원래 하려던 일이 아닌 것을 추가할 수 있게해줍니다.

예로 Int타입에 squared()라는 메서드를 추가해서 확장하면
최근 숫자를 제곱해서 반환해 줄 겁니다

extension Int {
    func squared() -> Int {
        return self * self
    }
}

실제로 확인해 봐야겠죠?
Int를 하나 생성해서 메서드를 사용해봅시다

let number = 8
number.squared()


잘 작동하네요

스위프트는 확장할 때 저장 프로퍼티를 추가하지 못하므로 연산프로퍼티를 써야합니다.
아래는 짝수인지 판단하는 것을 예시로 해봤어요

extension Int {
    var isEven: Bool {
        return self % 2 == 0
    }
}


함수가 아닌 연산프로퍼티라 ()은 필요없습니다.


Protocol extensions

프로토콜은 필수 요소들을 지정해주지만 내부적으로 코드를 제공하진 않죠
확장을 통해 해결할 수 있지만 한가지 데이터 타입만 사용할 수 있습니다

프로토콜 확장은 두 가지를 동시에 해결할 수 있습니다
일반적인 확장과 같지만 특정 데이터 유형만 확장하는게 아니라 전체를 확장한다는 차이점이 있습니다.

배열과 set이 있다고 합시다.

let pythons = ["Eric", "Graham", "John", "Michael", "Terry", "Terry"]
let beatles = Set(["John", "Paul", "George", "Ringo"])

스위프트에서 배열과 set은 둘다 Colletion이라는 프로토콜에 속해 있습니다.
그래서 여기에 summarize()라는 메서드를 확장하면 조금 더 멋있게 출력해줄 겁니다.

extension Collection {
    func summarize() {
        print("There are \(count) of us:")

        for name in self {
            print(name)
        }
    }
}
pythons.summarize()
beatles.summarize()


Protocol-oriented programming

프로토콜 확장은 프로토콜 메서드에 대한 기본 구현을 제공해 줍니다. 이를 통해 프로토콜을 쉽게 따를 수 있으며 프로토콜 지향 프로그래밍이라는 기술을 사용하여 프로토콜과 프로토콜 확장을 중심으로 코드를 제작할 수 있습니다.

먼저 Identifiable이라는 프로토콜을 만들어보죠
id프로퍼티와 identify()를 가집니다

protocol Identifiable {
    var id: String { get set }
    func identify()
}

모든 타입에 대해 그들만의 identify()메서드를 만들 수도 있지만
프로토콜 확장을 통해 기본값으로 제공할 수도 있습니다.

extension Identifiable {
    func identify() {
        print("My ID is \(id).")
    }
}

이제 Identifiable만족하는 타입을 만들면 identify()가 자동으로 동작합니다

struct User: Identifiable {
    var id: String
}

let twostraws = User(id: "twostraws")
twostraws.identify()


Summary

  1. 프로토콜은 메소드랑 프로퍼티가 따라야하는 요소들을 명시하지만 구현을 지원하지는 않습니다
  2. 클래스와 비슷하게 프로토콜은 상속을 지원합니다. 그것도 여러개!
  3. 확장은 Int같은 특정 타입에 메서드나 연산프로퍼티를 추가할 수 있습니다
  4. 프로토콜 확장은 프로토콜에 메서드나 연산프로퍼티를 추가하게 해줍니다
  5. 프로토콜 지향 프로그래밍은 앱 아키텍쳐를 프로토콜로 구성한다음 프로토콜 확장을 사용해서 기본 메서드의 구현을 하는 방식입니다
profile
초보 개발자 살아남기

0개의 댓글