본문에서 클래스라고 하곤 있지만 구조체에서도 똑같이 적용됨
프로토콜의 확장
- 프로토콜을 채택한 타입에서 실제 메서드를 구현할때 똑같은 코드를 반복해야하는 불편함을 제거
- 단순히 기본구현을 제공하는 개념
- 프로토콜의 확장에서 기본구현을 할시 클래스에서 구현을 안해도 기본구현된 내용으로 동작
- 단, 클래스에서 구현을 할시 클래스에서 구현한 내용이 동작
- 즉, 우선순위가 클래스에서 구현한것이 높고 확장에서 구현한것이 낮다
protocol Remote { // 본체에선 요구사항 정의만 가능
func turnOn()
func turnOff()
}
extension Remote { // 확장에서
func turnOn() {
print("켜짐")
}
func turnOff() {
print("꺼짐")
}
}
class TVRemote: Remote {
// 프로토콜의 확장에서 기본구현을 할시
// 채택한 타입에서 구현을 안해줘도 됨
// 그럴경우 프로토콜의 확장에서 기본구현한 동작으로 실행됨
func turnOn() { // 클래스에서 구현
print("tv켜짐")
}
}
let tvRemote: TVRemote = TVRemote()
tvRemote.turnOn() // 클래스에서 구현한 동작
/*
콘솔: tv켜짐
*/
tvRemote.turnOff() // 프로토콜의 확장에서 구현한 동작
/*
콘솔: 꺼짐
*/
- 프로토콜의 본체에서 요구사항 정의는 안했지만 확장에서 구현한경우
- 클래스에서 구현을 안할시 프로토콜에서 기본구현한 동작
protocol Remote {
func turnOn()
func turnOff()
}
extension Remote {
func turnOn() {
print("켜짐")
}
func turnOff() {
print("꺼짐")
}
// 요구사항 정의는 안했지만 확장에서 기본구현 한경우
func volumUp() {
print("볼륨업")
}
}
class TVRemote: Remote {
}
let tvRemote: TVRemote = TVRemote()
tvRemote.volumUp()
/*
콘솔: 볼륨업
*/
- 클래스에서 구현한경우
- 인스턴스의 타입이 해당 클래스인경우
- 클래스에서 구현된 메서드 실행
protocol Remote { // 본체에선 요구사항 정의만 가능
func turnOn()
func turnOff()
}
extension Remote { // 확장에서
func turnOn() {
print("켜짐")
}
func turnOff() {
print("꺼짐")
}
func volumUp() {
print("볼륨업")
}
}
class TVRemote: Remote {
func volumUp() {
print("tv 볼륨업")
}
}
let tvRemote: TVRemote = TVRemote() // 타입이 클래스
tvRemote.volumUp()
/*
콘솔: tv 볼륨업
*/
- 인스턴스의 타입이 채택된 프로토콜 타입인 경우
- 프로토콜의 확장에서 기본구현된 메서드 실행
protocol Remote { // 본체에선 요구사항 정의만 가능
func turnOn()
func turnOff()
}
extension Remote { // 확장에서
func turnOn() {
print("켜짐")
}
func turnOff() {
print("꺼짐")
}
func volumUp() {
print("볼륨업")
}
}
class TVRemote: Remote {
func volumUp() {
print("tv 볼륨업")
}
}
let tvRemote: Remote = TVRemote() // 타입이 프로토콜
tvRemote.volumUp()
/*
콘솔: 볼륨업
*/