# 활동학습 내용 아래 여러 상황에서 각각의 상황에 맞는 방법을 클래스의 상속과 프로토콜 기본 구현 중 골라서 직접 코드로 구현해보세요. 상황 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를 깎았다 ```