# 활동학습 내용
아래 여러 상황에서 각각의 상황에 맞는 방법을 클래스의 상속과 프로토콜 기본 구현 중 골라서 직접 코드로 구현해보세요.
상황 1 : 야곰 아카데미 구성원 각각의 역할을 표현하고 싶을 때 (ex : 캠퍼, 크루, 리더, 매니저, 서포터, 리뷰어 등 / 멤버의 역할은 디스코드에서 확인할 수 있습니다)
상황 2 : 각종 도형(삼각형, 사각형, 정사각형, 직사각형, 평행사변형 등등)을 타입으로 표현하고 싶을 때
상황 3 : 탈것(자동차, 승용차, 버스, 트럭, 기차, 보트, 비행기, 오토바이, 자전거, 퀵보드 등등)을 표현하고 싶을 때
상황 4 : 포켓몬(피카츄, 라이츄, 파이리, 꼬부기, 또가스, 또도가스, 잉어킹, 갸라도스 등등)을 표현하고 싶을 때
4개 중 3개 선택하여 진행
### 각각의 상황에서 해당 방식을 택한 이유는 무엇인가요?
* 야아: 클래스
* 이유: 멤버가 전부 야곰아카데미 소속이기 때문에 상속으로 해결할 수 있을 것 같아서 결정했다.
* 탈것 : 프로토콜
* 이유: 클래스의 상속으로 구현하면 탈것의 세부적인 기능을 표현하기 어려워서 프로토콜로 결정했다.
* 포켓몬: 클래스 + 프로토콜
* 이유: 포켓몬의 공통된 특징은 상속으로 구현하고 속성 별 기능을 프로토콜로 표현하면 효율적일 것 같아서 결정했다.
### 각 방식의 한계점에는 무엇무엇이 있을까요?
* 상속
* 상속 시, SuperClass에 원하지 않는 프로퍼티가 있어도 무조건 상속된다.
* 프로토콜 기본구현
* 기능을 상세하게 나누어 프로토콜로 구현할 때, 모든 프로토콜에 기본구현을 해주어야 하기 때문에 코드가 길어졌다.
### 클래스의 상속과 프로토콜 기본구현이 모두 가능한 상황이라고 가정한다면, 둘 중 하나의 방법으로 선택에 있어 고민해봐야 하는 지점은 무엇이 있을까요?
* override 가능성 - 상속으로 구현했을 때, 어떤 메서드를 계속 override한다면 protocol로 구현하는 것이 좋다고 생각합니다.
* 계층구조 - 후에 계층구조가 복잡해져서 다중상속을 해야하는 상황이 올 수 있다면 protocol을 채택하는게 좋다고 생각합니다.
* 확장성 - 나중에 기능이 추가되어야하는 경우 프로토콜을 사용하는 것이 기존 타입을 수정하지 않아도 돼서 유용하다고 생각합니다.
## 1. 야아
방법: 클래스
``` swift
class 야곰아카데미구성원 {
let 닉네임: String
func 디스코드채팅() {
print("아무말방에 글을 올린다")
}
init(닉네임: String) {
self.닉네임 = 닉네임
}
}
class 캠퍼: 야곰아카데미구성원 {
func TIL쓰기() {
print("잔디를 심어요")
}
}
class 크루: 야곰아카데미구성원 {
func 활동학습진행() {
print("활동학습을 진행해요")
}
}
class 리더: 야곰아카데미구성원 {
func 맥북쏟기() {
print("맥북을 쏟았어요 🥲")
}
func 콜라쏟기() {
print("콜라를 쏟았어요 🥲")
}
}
class 매니저: 야곰아카데미구성원 {
func 이벤트진행() {
print("이벤트를 진행해요")
}
}
class 서포터: 야곰아카데미구성원 {
func 캠퍼구제() {
print("울고있는 캠퍼를 도와줘요")
}
}
class 리뷰어: 야곰아카데미구성원 {
func 머지하기() {
print("흠 🤔 이정도면 됐다. 머지를 받아라.")
}
}
```
## 2. 탈것
방법: 프로토콜 기본 구현
``` swift
protocol 탈것 {
func 사람을태워유()
}
protocol 육지탈것: 탈것 {
var 바퀴수: Int { get set }
func 땅을달리다()
}
protocol 바다탈것: 탈것 {
func 바다를달리다()
}
protocol 하늘탈것: 탈것 {
var 날개수: Int { get set }
func 하늘을달리다()
}
extension 탈것 {
func 사람을태워유() {
print("로웬 고트 혜모리 태우기")
}
}
struct 자동차: 육지탈것 {
var 바퀴수 = 4
func 땅을달리다() {
print("부릉부릉")
}
}
struct 자전거: 육지탈것 {
var 바퀴수 = 2
func 땅을달리다() {
print("따릉따릉")
}
}
struct 보트: 바다탈것 {
func 바다를달리다() {
print("부우우웅")
}
}
struct 비행기: 하늘탈것 {
var 날개수 = 2
func 하늘을달리다() {
print("슈우우웅")
}
}
```
## 3. 포켓몬
방법: 클래스, 프로토콜
``` swift
class 포켓몬 {
let 이름: String
let 성별: String
init(이름: String, 성별: String) {
self.이름 = 이름
self.성별 = 성별
}
func 필살기사용() {
print("300의 HP를 깎았다")
}
}
protocol 속성 {
func 스킬()
}
protocol 물속성: 속성 {
func 헤엄()
}
protocol 불속성: 속성 {
func 익히기()
}
protocol 풀속성: 속성 {
func 로켓단날리기()
}
protocol 번개속성: 속성 {
func 플래쉬()
}
extension 물속성 {
func 헤엄() {
print("어푸어푸")
}
}
extension 불속성 {
func 익히기() {
print("화르르륵")
}
}
extension 풀속성 {
func 로켓단날리기() {
print("뽀로로록")
}
}
extension 번개속성 {
func 플래쉬() {
print("쨍-")
}
}
class 피카츄: 포켓몬, 번개속성 {
func 스킬() {
print("백만볼트")
}
}
class 파이리: 포켓몬, 불속성 {
func 스킬() {
print("불대문자")
}
}
class 꼬부기: 포켓몬, 물속성 {
func 스킬() {
print("물대포")
}
}
class 이상해씨: 포켓몬, 풀속성 {
func 스킬() {
print("씨뿌리기")
}
}
let 삐까츄 = 피카츄(이름: "피카츄", 성별: "수컷")
삐까츄.스킬() // 백만볼트
삐까츄.플래쉬() // 쨍-
삐까츄.필살기사용() // 300의 HP를 깎았다
```