# Protocol Oriented Programming
- 상황 1 : 야곰 아카데미 구성원 각각의 역할을 표현하고 싶을 때 (ex : 캠퍼, 크루, 리더, 매니저, 서포터, 리뷰어 등)
- 상황 3 : 탈것(자동차, 승용차, 버스, 트럭, 기차, 보트, 비행기, 오토바이, 자전거, 퀵보드 등등)을 표현하고 싶을 때
- 상황 4 : 포켓몬(피카츄, 라이츄, 파이리, 꼬부기, 또가스, 또도가스, 잉어킹, 갸라도스 등등)을 표현하고 싶을 때
### 각각의 상황에서 해당 방식을 택한 이유는 무엇인가요?
- 공통적으로 갖는 속성을 표현하기 위해서 프로토콜로 정의해주었습니다. 하지만, 포켓몬의 경우에선 진화라는 수직적인 관계를 포함하고 있다고 판단하여 상속으로 정의해주었습니다.
### 각 방식의 한계점에는 무엇무엇이 있을까요?
#### 상속
- 수직적인 표현에 국한되어서 표현이 되기 때문에 수평적으로 표현하고 싶은 타입에 대해서 확장하는 것이 한계가 있었습니다.
#### 프로토콜
- objective-c의 프로토콜은 확장하지 못합니다.
### 클래스의 상속과 프로토콜 기본구현이 모두 가능한 상황이라고 가정한다면, 둘 중 하나의 방법으로 선택에 있어 고민해봐야 하는 지점은 무엇이 있을까요?
- 이거 어케 적을까용? ㅋㅋㅋㅋㅋ
-
### 포켓몬
```swift
// MARK: Protocol Oriented Programming
// TODO: - 포켓몬
// 피카츄, 파이리 - protocol
// 라이츄
protocol PokemonAble {
var element: String { get } // 속성
var health: Int { get } // HP
func skill1()
func skill2()
}
extension PokemonAble {
func skill1() {
print("몸통박치기")
}
}
protocol 피카츄어블: PokemonAble {}
extension 피카츄어블 {
func skill2() {
print("백만볼트")
}
}
protocol 파이리어블: PokemonAble {}
extension 파이리어블 {
func skill2() {
print("불대문자")
}
}
class 피카츄: 피카츄어블 {
var element: String = "전기"
var health: Int = 100
}
class 라이츄: 피카츄 {}
class 파이리: 파이리어블 {
var element: String = "불"
var health: Int = 100
}
let myPikacu = 라이츄()
myPikacu.skill2()
```
### 야곰아카데미
```swift
protocol YagomAble {
var nickName: String { get }
func doSwift()
}
extension YagomAble {
func doSwift() {
print("Swift 하는중... 머리 빠지는 중...")
}
}
protocol Workable {}
protocol teachable {
func doStudyActivity()
} // 학습활동을 주관할 수 있다.
extension teachable {
func doStudyActivity() {
print("학습활동 하는 중 7기 잘하누...")
}
}
protocol Crewable: YagomAble, Workable, teachable { }
protocol Leaderable: YagomAble, Workable, teachable { }
protocol Supportable: YagomAble, Workable { }
protocol Reviewable: YagomAble, Workable { }
protocol Campable: YagomAble { }
struct Camper: Campable {
var nickName: String
}
struct Leader: Leaderable {
var nickName: String
}
let woong = Camper(nickName: "woong")
let inho = Camper(nickName: "inho")
let minii = Camper(nickName: "minii")
let yagom = Leader(nickName: "yagom")
woong.doSwift()
inho.doSwift()
minii.doSwift()
yagom.doStudyActivity()
```
### 탈것
```swift
// 자동차 : 승용차, 버스, 트럭
// 나는 거 : 비행기
// 헬멧을 써야 하는 것 : 오토바이, 자전거, 퀵보드
// 물에서 사용 하는 것 : 보트
// 레일에서 활용하는 것 : 기차
// 티켓을 활용하는 것 : 버스, 비행기, 기차
protocol ridable {
var tireCount: Int { get }
}
protocol carable: ridable {
func drive()
}
extension carable {
func drive() {
print("붕붕")
}
}
protocol flyable: ridable { }
protocol helmatable: ridable { }
protocol waterable: ridable { }
protocol railable: ridable { }
protocol ticketable: ridable {
var cost: Int { get }
func sale() -> Int
}
extension ticketable {
func sale() -> Int {
let saledCost = Double(cost) * 0.8
return Int(saledCost)
}
}
struct 승용차: carable {
var tireCount: Int = 4
}
struct 버스: carable, ticketable {
var tireCount: Int = 4
var cost: Int = 1250
}
struct 비행기: flyable, ticketable {
var tireCount: Int = 3
var cost: Int = 1000_0000
}
struct 오토바이 : helmatable {
var tireCount: Int = 2
}
struct 보트: waterable {
var tireCount: Int = 0
}
struct 기차: railable, ticketable {
var tireCount: Int = 12
var cost: Int = 19800
}
let Sclass = 승용차()
Sclass.drive()
let A380 = 비행기()
print(A380.sale())
```
```swift
// 전체 코드
// MARK: Protocol Oriented Programming
// TODO: - 포켓몬
// 피카츄, 파이리, 꼬부기, 이상해씨, 또가스, 잉어킹 - protocol
// 라이츄
// 진화의 속성은 상속으로 표현할 것인가?
protocol PokemonAble {
var element: String { get } // 속성
var health: Int { get } // HP
func skill1()
func skill2()
}
extension PokemonAble {
func skill1() {
print("몸통박치기")
}
}
protocol 피카츄어블: PokemonAble {}
extension 피카츄어블 {
func skill2() {
print("백만볼트")
}
}
protocol 파이리어블: PokemonAble {}
extension 파이리어블 {
func skill2() {
print("불대문자")
}
}
class 피카츄: 피카츄어블 {
var element: String = "전기"
var health: Int = 100
}
class 파이리: 파이리어블 {
var element: String = "불"
var health: Int = 100
}
class 라이츄: 피카츄 {}
let myPikacu = 라이츄()
myPikacu.skill2()
let myPilry = 파이리()
myPilry.skill2()
// MARK: 야곰 아카데미
//
// 크루, 리더, 서포터, 리뷰어
// 캠퍼,
/* 공통점
- 야곰 아카데미 소속이다.
- Swift 언어를 사용할 줄 안다.
*/
protocol YagomAble {
var nickName: String { get }
func doSwift()
}
extension YagomAble {
func doSwift() {
print("Swift 하는중... 머리 빠지는 중...")
}
}
protocol Workable {}
protocol teachable {
func doStudyActivity()
} // 학습활동을 주관할 수 있다.
extension teachable {
func doStudyActivity() {
print("학습활동 하는 중 7기 잘하누...")
}
}
protocol Crewable: YagomAble, Workable, teachable { }
protocol Leaderable: YagomAble, Workable, teachable { }
protocol Supportable: YagomAble, Workable { }
protocol Reviewable: YagomAble, Workable { }
protocol Campable: YagomAble { }
struct Camper: Campable {
var nickName: String
}
struct Leader: Leaderable {
var nickName: String
}
let woong = Camper(nickName: "woong")
let inho = Camper(nickName: "inho")
let minii = Camper(nickName: "minii")
let yagom = Leader(nickName: "yagom")
woong.doSwift()
inho.doSwift()
minii.doSwift()
yagom.doStudyActivity()
// MARK: 탈것
// 공통 : 바퀴수?
// 속도를 기준으로 나눈다.
//
// 자동차 : 승용차, 버스, 트럭
// 나는 거 : 비행기
// 헬멧을 써야 하는 것 : 오토바이, 자전거, 퀵보드
// 물에서 사용 하는 것 : 보트
// 레일에서 활용하는 것 : 기차
// 티켓을 활용하는 것 : 버스, 비행기, 기차
protocol ridable {
var tireCount: Int { get }
}
protocol carable: ridable {
func drive()
}
extension carable {
func drive() {
print("붕붕")
}
}
protocol flyable: ridable { }
protocol helmatable: ridable { }
protocol waterable: ridable { }
protocol railable: ridable { }
protocol ticketable: ridable {
var cost: Int { get }
func sale() -> Int
}
extension ticketable {
func sale() -> Int {
let saledCost = Double(cost) * 0.8
return Int(saledCost)
}
}
struct 승용차: carable {
var tireCount: Int = 4
}
struct 버스: carable, ticketable {
var tireCount: Int = 4
var cost: Int = 1250
}
struct 비행기: flyable, ticketable {
var tireCount: Int = 3
var cost: Int = 1000_0000
}
struct 오토바이 : helmatable {
var tireCount: Int = 2
}
struct 보트: waterable {
var tireCount: Int = 0
}
struct 기차: railable, ticketable {
var tireCount: Int = 12
var cost: Int = 19800
}
let Sclass = 승용차()
Sclass.drive()
let A380 = 비행기()
print(A380.sale())
```