20-3. 프로토콜의 상속, 프로토콜의 구성, 준수성 검사

🌈 devleeky16498·2022년 4월 21일
0

프로토콜 상속(protocol inheritance)

  1. 프로토콜은 하나 또는 그 이상의 다른 프로토콜을 상속할 수 있고, 상속한 요구사항 위에 요구사항을 더 추가할 수 있다.
protocol InheritanceProtocol : SomeProtocol, AnotherProtocol {
	//프로토콜 개념
}

protocol PrettyTextRepresentable : TextRepresentable {
	var prettyTextualDescription : String { get }
}
//이 친구는 기존의 textRepresentable이라는 프로토콜을 상속하는 프로토콜이다.
//상속하게 되는 경우 상속하는 하위 프로토콜은 수퍼 프로토콜의 프로퍼티와 메서드, 서브 스크립트를 모두 구현해줘야 한다. 

클래스 전용 프로토콜(Class-only-Protocol)

  1. 프로토콜 채택을 프로토콜의 상속 목록에 AnyObject 프로토콜을 추가해서 구조체 또는 열거형이 아닌 클래스 타입으로 제한할 수 있다.
protocol SomeClassOnlyProtocol : AnyObject, SomeInheritedProtocol {
	//class-only Protocol
}
// 이 프로토콜은 클래스 타입에서만 채택될 수 있다. 이를 구조체나 열거형에서 채택하는 경우 에러가 난다.
  1. 프로토콜의 요구사항에 의해 정의된 동작이 준수하는 타입에 값이 아닌 참조체계에 의미가 있다고 보이는 경우 클래스 전용 프로토콜을 채택한다.

프로토콜의 구성

  1. 동시에 여러개의 프로토콜을 준수하는 타입을 요구하는게 유용할 수 있다.
protocol Named {
	var name : String {get} 
}

protocol Aged {
	var age : Int {get}
}

struct Person : Named, Aged {
	var name : String
    var age : Int
}

func wishHappyBirthday(to celebrator : Named & Aged) {
//여기 위에서 celebrator 파라미터 타입은 Named & Aged로서 두 개의 프로토콜을 모두 준수하는 타입이라는 의미를 갖는다.
	print("Happy Birthday! \(celebrator.name), you're \(celebrator.age)")
    
 let birthdayPerson = Person(name : "Malcom", age : 21)
 wishHappyBirthday(to : birthdayPerson)
 //다음 함수는 유효하다. birthdayPerson의 구조체가 프로토콜을 준수하기 때문이다.

프로토콜 준수성 검사

  1. 프로토콜 준수성에 대해서 확인하고 특정 프로토콜로 캐스팅 하기 위하여 is와 as연산자를 사용할 수 있다.
  • is 연산자는 인스턴스가 프로토콜을 준수한다면 true를 반환하고 그렇지 않으면 false를 반환한다.
  • as?버전은 프로토콜의 타입으로 옵셔널 값을 반환하고 인스턴스가 준수하지 않는 경우 nil을 반환한다.
  • as!는 준수하지 않는 경우 런타임 에러를 트리거 한다.
protocol HasArea {
	var area : Double {get}
}

//다음은 HasArea프로토콜을 준수하는 Circle과 country 2개의 클래스이다.
class Circle : HasArea {
	let pi = 3.14
    var radius : Double
    var area : Double {return pi*radius*radius}
    init(radius : Double) {
    	self.radius = radius
    }
}

class Country : HasArea {
	var area : Double
    init(area : Double) {self.area = area}
}

//다음은 프로토콜을 준수하지 않는 다른 클래스이다.
class Animal {
	var legs : Int
    init(legs : Int) {self.legs = legs}
}

//여기에 대해서 오브젝트 배열을 선언한다.
let objects : [AnyObject] = [Circle(radius : 2.0), Country(area : 244), Animal(legs : 4)]

//다음에 대해서 준수성 검사를 시행한다.

for object in objects {
	if let objectWithArea = object as? HasArea {
    	print("Area is \(objectWithArea.area)")
    } else {
    	print("Something that doesn't have an Area")
    }
}
//여기에서는 배열의 객체가 HasArea프로토콜을 준수할 때마다 as?연산자에 의해 옵셔널 값이 반환되고, 
//상수에 옵셔널 바인딩 된다. 그리고 안전하게 출력 가능하다.
profile
Welcome to Growing iOS developer's Blog! Enjoy!🔥

0개의 댓글