모바일/SwiftUI ios 공부

프로토콜 protocols 정의 채택, 프로토콜 프로퍼티, 프로토컬 메서드, 프로토컬 이니셜라이저, 프로토컬 익스텐션 (extension)/ Xcode SwiftUI Playground 공부

yy_dd2 2021. 11. 29. 01:31
반응형

프로토콜(protocol)

특정 작업이나 기능에 적합한 메소드, 프로퍼티 등 기타 요구사항의 '약속'

 - 클래스, 구조체, 열거형에서는 어떠한 프로토콜을 채택하여 해당 프로토콜의 요구사항을 실제로 구현할 수 있다.

 - 프로토콜의 요구사항을 충족시키는 모든 타입은 해당 프로토콜을 준수한다 혹은 따른다고 한다

 

프로토콜 정의하기

 1. protocol 키워드를 앞에 붙이고, 프로토콜의 이름을 작성합니다.

 2. 아래는 SomeProtocol을 정의한 코드입니다.

 protocol 이름 {
 
 }
protocol SomeProtocol {
    
}
protocol SomeProtoco2 {
    
}

 

프로토컬 채택하기

 1. 클래스, 구조체, 열거형에서 정의한 프로토콜을 채택 위해 콜론(:) 사용

struct SomeStructrue : SomeProtocol {
    
}

 2. 하나의 타입에서 다수의 프로토콜을 채택하기 위해서는 콤마(,)를 사용

// 여러개의 프로토콜 채택하기
struct SomeStructrue2 : SomeProtocol, SomeProtoco2 {
    
}

 3. 클래스에서 상속과 프로토콜 채택을 동시에 하려면 상속받으려는 클래스를 먼저 명시하고, 그 뒤에 채택할 프로토콜 목록을 작성

// 클래스 프로토콜 채택하기
//클래스에서 상속과 프로토콜 채택을 동시에 하려면 상속받으려는 클래스를 먼저 명시하고, 그 뒤에 채택할 프로토콜 목록을 작성합니다.

// SomeClass: SomeSuperclass, -> 상속
// FirstProtocol, AnotherProtocol -> 2개의 프로토콜
 
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
    
}

 


 

프로토콜의 프로퍼티 요구사항

 프로토콜은 자신을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구할 수 있다

1. 프로퍼티는 타입과 이름만작성 (프로토콜이 프로퍼티에 준수하도록 정의할때 저장 프로퍼티인지 계산 프로퍼티인지 지정하지 않고 프로퍼티 이름과 타입만 정의하면 된다.)

2. gettable/settable 여부를 작성 (읽기만 가능한지 읽기 쓰기가 모두 가능한지 지정 / 프로토컬에서 읽기만 가능한 프로퍼티를 요구하는 경우 모든 종류의 프로퍼티를 사용할 수 있다)

3. 프로퍼티는 var로 선언해야 한다

protocol FirstProtocol {
    var name: Int { get set}
    var age: Int { get }            // 읽기 전용
}

// 프로토콜에서 타입 프로토콜을 요구 할 때는 static 키워드를 사용해야 한다
protocol AnotherProtocol {
    static var someTypeProperty: Int { get set}
}

// 프로토콜에서 프로퍼티 요구사항을 정의하고 구조체에 정의한 프로토컬 채택하기
protocol FullyNames {
    var fullName: String { get set}
}
// 이렇게만 쓰면 에러
/*
프로토컬이 요구하는 사항을 모두 준수하지 않았다
struct Person: FullyNames {
    
}
*/
// 정의해주면 오류가 나지 않는다.
struct Person: FullyNames {
    var fullName: String
}

 

프로토콜 메서드 / 프로토콜 메소드

1. 메소드는 함수명과 반환값을 지정할 수 있고,메소드 내용을 작성하지 않아도 된다

protocol FullyNames2 {
    var fullName2: String { get set}
    func printFullName2()
}
struct Person2: FullyNames2 {
    var fullName2: String
    
    func printFullName2() {
        print(fullName2)
    }
}
protocol SomeProtocol3 {
    func someTypeMethod( )
}

 


프로토콜 이니셜라이저

 1. 프로토콜에서는 필수로 구현해야하는 이니셜라이저를 지정할 수 있다

 2. 이니셜라이저가 있는 프로토콜을 채택한 타입에서는 해당 이니셜라이저에 required 키워드를 작성해야 한다

protocol SomeProtocol4 {
    init(someParameter: Int)
}

protocol SomeProtocol5 {
    init( )
}
/*
// 생성자 요구사하 준수하지 않은 에러
class SomeClass: SomeProtocol5 {
    
}
*/
class SomeClass: SomeProtocol5 {
    required init() {
        
    }
}

 


프로토컬 익스텐션

extension ?

기존의 클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가하는 기능

1. 익스텐션이 타입에 추가할 수 있는 기능

 1) 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티

 2) 타입 메서드 / 인스턴스 메서드

 3) 이니셜라이저

 4) 서브스크립트

 5) 중첩 타입

 6) 특정 프로포콜을 준수할 수 있도록 기능 추가

2. 이미 존재한 기능을 오버라이드 못함

 

 

extension 연산 프로퍼티 메서드 기능 추가

extension SomeType {

 // 추가 기능

 }

extension을 사용해 타입에 연산 프로퍼티를 추가하기

- 연산 프로퍼티는 추가가 가능하지만 저장 프로퍼티는 추가하지 못한다

// 짝수 홀수 판단하는 extension 프로퍼티 추가
extension Int {
    // 짝수 true 홀수 false
    var isEven: Bool{
        return self % 2 == 0
    }
    
    var isOdd: Bool {
        return self % 2 == 1
    }
}

var number = 3
number.isOdd
number.isEven

 

타입의 메서드를 추가해보기

// 타입의 메서드를 추가해보기
// String 타입을 Int 타입으로으로 바꿔주기 (형변환)
extension String {
    func convertToInt() -> Int? {
        return Int(self)
    }
}

var string = "0"
string.convertToInt()

 

 

반응형