[iOS] Protocol

r1verfuture·2022년 4월 14일
0

iOS

목록 보기
20/30

Protocol

  • 특정 역할을 수행하기 위한 메소드, 프로퍼티, 기타 요구사항 등의 청사진을 정의한다.
  • 구조체, 클래스, 열거형은 프로토콜을 채택 (Adopt) 해서 특정 기능을 수행하기 위한 프로토콜의 요구사항을 실제로 구현할 수 있다.
  • 어떤 프로토콜의 요구사항을 모두 따르는 것을 그 프로토콜을 준수 (Conform) 한다고 표현한다.
  • 프로토콜의 요구사항을 충족시키려면 프로토콜이 제시하는 청사진의 기능을 모두 구현해야 한다.
  • 프로토콜은 기능을 정의하고 제시할 뿐이지 기능을 구현하지는 않는다.

프로토콜 정의

// MARK: [코드 1] 프로토콜 정의 형태
protocol MyProtocol {
	
}

프로토콜 채택

// MARK: [코드 2] 프로토콜 채택 형태
struct MyStruct : MyProtocol {
	
}

class MyClass : MyProtocol {

}

enum MyEnum : MyProtocol {

}
  • [코드 2] : 'MyStruct' 구조체, 'MyClass' 클래스, 'MyEnum' 열거형 모두 'MyProtocol' 프로토콜을 채택했다.
  • 다른 클래스를 상속받는 동시에 프로토콜을 채택하는 클래스를 만들 때는 상속받을 클래스 이름 먼저 작성하고, 그 뒤에 채택할 프로토콜 이름을 작성하면 된다.

프로퍼티 요구

  • 프로토콜은 자신을 채택한 타입이 어떤 프로퍼티를 구현해야 하는지 요구할 수 있다.
  • 프로토콜을 채택한 타입은 프로토콜이 요구하는 프로퍼티의 이름과 타입만 맞게 구현해주면 된다.
  • 프로퍼티를 읽기만 가능하도록 할지, 읽기 & 쓰기 모두 가능하도록 할지는 프로토콜이 정해야 한다.
  • 프로토콜의 프로퍼티 요구사항은 항상 var 키워드를 사용한 변수 프로퍼티로 정의된다.
  • 읽고 쓰기 모두 가능한 프로퍼티는 프로퍼티 정의 뒤에 { get set } 이라고 써주고, 읽기만 가능한 프로퍼티는 프로퍼티 정의 뒤에 { get } 이라고 써주면 된다.
// MARK: [코드 3] 프로토콜 프로퍼티 작성 요령
protocol MyProtocol {
	var readAndWriteProperty : String { get set }
    var readOnlyProperty : String { get }
}
  • [코드 3] : 'readAndWriteProperty' 프로퍼티는 읽고 쓰기 모두 가능하도록 정의되었고, 'readOnlyProperty' 프로퍼티는 읽기만 가능하도록 정의되었다.
// MARK: [코드 4] 프로토콜 생성 후 그 프로토콜을 채택하는 클래스 생성 (프로퍼티 요구)
protocol MyProtocol {
	var readAndWriteProperty : String { get set }
}

class MyClass : MyProtocol {
	var readAndWriteProperty : String
}
  • [코드 4] : 'readAndWriteProperty' 프로퍼티가 프로토콜 안에 정의되었기 때문에 그 프로토콜을 채택한 'MyClass' 클래스는 반드시 'readAndWriteProperty' 프로퍼티를 선언해주어야 한다.

메소드 요구

  • 프로토콜은 특정 인스턴스 메소드나 타입 메소드를 요구할 수도 있다.
  • 프로토콜이 요구할 메소드는 프로토콜 정의에서 작성하는데, 메소드의 실제 구현부 ('{}') 는 제외하고 메소드의 이름 & 매개변수 & 반환 타입 등만 작성한다.
  • 프로토콜의 메소드 요구에서는 매개변수 기본값을 지정할 수 없다.
// MARK: [코드 5] 프로토콜 생성 후 그 프로토콜을 채택하는 클래스 생성 (프로퍼티 & 메소드 요구)
protocol Information {
	var name : String { get set }
    var age : Int { get set }
    func printMyInformation(name : name, age : age)
}

struct MyInformation : Information {
	var name : String
    var age : Int
    
    func printMyInformation(name : name, age : age) {
    	print("Name = \(name), Age = \(age)")
    }
}

이니셜라이저 요구

  • 프로토콜은 특정한 이니셜라이저를 요구할 수도 있다.
  • 프로토콜에서 이니셜라이저를 요구하려면 메소드 요구와 마찬가지로 이니셜라이저를 정의만 해놓고, 구현은 하지 않는다. (이니셜라이저의 매개변수를 지정만 해놓고, 중괄호로 구현부를 만들지는 않는다.)
// MARK: [코드 6] 프로토콜 생성 후 그 프로토콜을 채택하는 클래스 생성 (프로퍼티 & 메소드 & 이니셜라이저 요구)
protocol Communication {
	var talker : String { get set }
    func talk(to : Information)
    init(talker : String, listener : String)
}

struct Information : Communication {
	var talker : String // Communication 프로토콜에 의해 요구된 프로퍼티
    var listener : String // Information 구조체 안에 따로 정의한 프로퍼티
    
    func talk(information : Information) {
    	print("\(talker)\(information.listener) 에게 말하는중 ~")
    }
    
    init(talker : String, listener : String) {
    	self.talker = talker
        self.listener = listener
    }
}

let r1verfuture : Information = Information(talker : "r1verfuture", listener : "whatso")
let whatso : Information = Information(talker : "whatso", listener : "r1verfuture")

r1verfuture.talk(to : whatso) // "r1verfuture 이 whatso 에게 말하는중 ~" 이라고 출력된다.

프로토콜의 채택

  • 프로토콜은 하나 이상의 프로토콜을 채택받아 기존 프로토콜의 요구사항보다 더 많은 요구사항을 추가할 수 있다.
  • 프로토콜 채택 문법은 클래스의 상속 문법과 비슷하다.
// MARK: [코드 7] 프로토콜 채택 예시
protocol Readable {
	func read()
}

protocol Writeable {
	func write()
}

// Readable 프로토콜을 채택한 ReadSpeakable 프로토콜
protocol ReadSpeakable : Readable {
	func speak()
}

// Readable, Writeable 프로토콜을 채택한 ReadWriteSpeakable 프로토콜
protocol ReadWriteSpeakable : Readable, Writeable {
	func speak()
}

// Able 클래스 는 ReadWriteSpeakable 프로토콜을 채택했기 때문에 ReadWriteSpeakable 프로토콜이 요구하는 사항들을 모두 준수해야 한다.
class Able : ReadWriteSpeakable {
	func read() {
    	print("I am reading !")
    }
    
    func write() {
    	print("I am writing !")
    }
    
    func speak() {
    	print("I am speaking !")
    }
}

참고

profile
#iOS #Swift #Developer #Python

0개의 댓글

관련 채용 정보