다중 상속
- C++ 만의 특성 : 다중 상속 지원
- 다중 상속이란? -> 부모가 2개 이상 있는 애
- 다른 언어와 java는 X – interface라는 애를 이용하여 다중 상속처럼 효과
- 다른 언어에서 없는 근본적 이유 – 모호함 발생한다.
모호함이란?
- A, B클래스 만들어 주고
- A, B 클래스 상속받은 C 클래스
- C 클래스 c 객체를 만들었다.
- 이 c 객체로 value나 info 함수에 접근하려고 할 때
- 누구의 함수이냐? A냐 B냐.
- 누구의 value( ) 인지 info( ) 인지 명확하게 해줘야 한다.
모호함이 있어도 괜찮은 경우
- 서로 이질적인 클래스의 부모들을 상속받을 경우
- ex) 자동차 클래스와 사람의 클래스를 상속받는 경우
- 서로 같은 부분이 많지는 않을 것이다. - 이럴 경우에는 괜찮다고 한다.
- ex) 스마트폰은 –> 컴퓨터와 폰을 합쳐서 나온 스마트폰
- 이런 경우에는 괜찮다고 한다. - 융합의 개념
인간은 무 -> 유 만드는 것 불가능
있는 것에서 있는 것을 만든다. - 있는 것에 있는 것을 합쳐서 새로운 것을 만드는 것!
다중 상속을 상속할 경우 - 주의해야 할 점 있지만 - 무조건 안된다는 생각은 하지 말기!
다형성
▣ 캡슐화 - 클래스 만드는 방법
▣ 상속 - 클래스 간의 관계 맺는 방법
▣ 다형성 - 객체 간의 관계를 맺는 방법
polymorphism
- 객체 간의 관계를 맺는 방법
- 객체가 같은 메시지에 다른 반응을 보이는 것 - 다형성.
- 다형성을 구현하는 방식 ( 오버 로딩 - 오버라이드 )
- Overloading - 오버 로딩 – 같은 이름의 함수를 만들어서 다른 반응 유도
- Override - 오버라이드 – 부모의 함수를 자식이 재정의 하여 다른 반응 유도
객체 지향
- A에서 D로 - D에서로 B로 등등 - 메시지를 보냈다.
- 객체가 있고 메시지가 왔다 갔다 하는 것이 - 객체 지향
- A 객체가 D 객체에게 메시지를 보냈다의 의미는?
- 객체의 함수를 호출한다는 의미!
- A 객체가 - D 객체의 멤버 함수를 호출한다는 의미
위의 객체 지향의 기본 개념 ( 메시지를 보냈다의 의미는 그 객체의 함수를 호출한다는 의미 )
숙지한 후 - 실습을 통하여 다형성을 배워보자
실습 순서
- 클래스 기본 세팅
- 오버 로딩을 통한 다형성
- 상속의 구조를 통한 다형성
- 오버 라이딩을 통한 다형성
기본 세팅
: 상황 – 커피샾 관리 프로그램 개발 의뢰
만들어야 할 프로그램의 기본 틀 잡기
1. 업무 흐름 파악 ( 역할과 책임 )
- 역할 – 캐셔, 바리스타, 손님, - 각각의 객체 클래스 만들기
- 책임 – 주문받기, 커피 만들기, 주문 하기 – 역할에 맞는 함수 만들기
4. 세 개의 객체( 캐셔, 바리스타, 손님) - 생성! 따로따로 있는 상태 - 연결 안 된 상태
5. 관계를 만들어줘야 한다. - 지속적인 관계인지 일시적인 관계인지 판단
6. 게스트는 캐셔를 잠깐 알면 된다. - 의존적관계 – 주문하면 끝
7. 캐셔와 바리스타는 – 지속적인 관계 – but 생명주기를 같이해야 한다? 그건NO
8. 공간에 있을 때만 알고 있다가 퇴근하면 남남 – 관계 유지할 필요 X -
9. 캐셔는 바리스타를 잠깐 알고 있으면 된다. 15번 line/번line/
10. 18번 line 바리스타와 관계 이어준다.
11. 커피샾에 바리스타 한 명인가? 여러명일수도있다.- 그때그때마다 맺을 건가? 선택
즉!!
역할에 맞는 - 객체 생성
책임에 따른 - 함수 위치와 기능 생성
관계에 따라 - 포함, 참조 결정
기본 세팅 시작
바리스타의 역할 - 책임 - 관계
게스트의 역할 - 책임 - 관계
게스트는 캐셔한테 주문하는 메시지를 보낸다. - OrderingDrink( )
메시지를 보낸다의 의미는 =캐셔의. OrderedDrink( ) 함수를 호출한다는 의미
관계 : 게스트는 캐셔를 잠깐 알면 된다. 의존적– 주문하면 끝
캐셔의 역할 - 책임 - 관계
캐셔는 게스트에게 음료 주문을 받는다. - OrderedDrink( )
캐셔는 바리스타한테 주문받은 음료를 만들어 달라는 메시지를 보낸다. - MakeDrink( )
메시지를 보낸다의 의미는 = 바리스타의 . MakeDrink( )함수를 호출한다는 의미
관계 : 캐셔와 바리스타는 – 커피샾에 있는 동안은 관계를 유지하고 있는 관계
- 포함관계로 해준다.
- 포함 중에서도 Aggregation 관계 - 생명주기 같이하지 않는다.
- composition관계 X
main 객체 생성 / 테스트
기본 세팅 끝
오버 로딩을 통한 다형성 시작
커피 클래스 추가
게스트 부분 - OrderingDrink( ) 수정
캐셔 부분 - OrderedDrink( ) 수정
바리스타 부분 - MakeDrink( ) 수정
메뉴가 하나가 아니다. 음료를 또 만들자.
Aid추가 – 게스트에는 Aid 주문하는 함수 필요 - OrderingDrink( )
Aid추가 – 캐셔에는 Aid 주문받는 함수 필요 - OrderedDrink( )
Aid추가 – 바리스타에는 Aid 만드는 함수 필요 - MakeDrink( )
메뉴 Aid를 추가한 상황에서도
게스트는 주문할 때 OrderingDrink( ) 함수 사용 - 인자 값만 다르게 전달 - Coffee 또는 Aid만 다르게 전달
캐셔는 주문받을 때- OrderedDrink( ) 함수 사용 -
바리스타는 음료 만드는 MakeDrink( ) 함수 사용 -
여기서
게스트는 Coffee 또는 Aid로 캐셔한테 OrderedDrinnk( ) 주문을 보내고 있다.
여기서 캐셔가 받은 것은 OrderedDrink( ) 같은 함수의 요청을 받았지만.
인자가 Coffee가 들어오면 --> 커피 만들어달라고 바리스타에게 전달
인자가 Aid가 들어오면 --> aid 만들어달라고 바리스타에게 전달
오버 로딩을 이용한 다형성!
- 클래스 안에다 같은 함수를 넣어가지고 다양한 반응을 내도록 해본 것 – 다형성 오버 로딩
상속으로 구조변경 스타트
이렇게 만들어놨는데 메뉴가 계속 늘어난다면?
Tea 추가 --
- 게스트 부분 – Tea 주문하는 함수 추가
- 캐셔 부분 – Tea 아더 함수 추가
- 바리스타 부분 – Tea 메이커 함수 추가
- 메인 부분 – tea 객체 만들고 guest.OrderingDrink(tea, cashier);
계속 다 추가해주어야 한다..
메뉴 추가될 때마다 추가해줄 부분이 많다..
음료 추가되는 것 때문에 추가해줄 부분이 많다.
해결할 수 있는 방법은?? - 음료 상속!!
상속의 구조로 변경
어우를 수 있는 클래스 하나 만들고 – Class Drink - 공통적인 부분 빼오고 생성자 만들어주기
부모 타입으로 자식 타입 받을 수 있다
캐셔의 OrderedDrink( )와 바리스타의 MakeDrink ( )에coffee / tea / aid 따로 만들어줬던 함수들
Drink로 하나만 남겨주기
" 상속 관계로 만들기 끝 "
+@ 상속처리 끝난 상태에서 음료 추가해보기
class Milk : public Drink 만 해주면 끝!
아까는 Milk 추가되면 milk 클래스, 게스트 클래스, 캐셔 클래스, 바리스타 클래스에서 함수 추가 필요했지만
이제는 Drink 상속 Milk클래스만 만들어주면 끝!
main부분 check
오버 라이딩을 통한 다형성 시작
현재 음료 만드는 책임을 바리스타 가지고 있다.
그런데 음료는 누가 제일 잘 알죠? -> Drink 가 제일 잘 안다.
이 책임을 Drink에게 넘긴다.
why ?
바리스타가 만드는 부분 가지고 있으면 들어온 음료에 대해 만드는 방법 다 가지고 있어야 한다
그래서 음료를 제일 잘 아는 Drink 부분에다가 넘긴다!
1. 바리스타 MakeDrink( ) 함수에서 "음료를 만듭니다" 대신 -----> "음료를 만드는 요청을 합니다"로 변경
2. Drink 클래스의 MakeADrink ( ) 만들어 준다.
3. 문제 발생
문제는 부모인 Drink 클래스의 MakeADrink( ) 만 다 호출 – 출력 확인 ( "음료를 만듭니다." 만 출력 )
들어온 인자 값에 따라 - MakeADrink( ) 가 다르게 호출되도록해주고 싶다..
방법은? - 가상 virtual 함수로 변경!
일반 함수인 경우에는 담는 그릇 - ( 데이터 타입 ) 의 함수를 호출해서 준다
가상 함수인 경우에는 들어온 타입에 맞춰 그릇 안에 있는 데이터 타입의 함수를 호출해서 준다.
4. 각각의 음료 만드는 방법은 각각의 클래스 애들이 가지고 있다. ( 부모인 Drink클래스X )
5. 결론
상속관계에서 자식이 부모의 함수를 덮어써서 사용한 경우를 -
오버라이드를 이용한 다형성이라 한다.
정확히 말하자면 부모의 가상 함수를– 자식이 재정의하는 것!
Override - 오버라이드
- 함수 뒤 override 생략 가능하지만 써주면 부모 함수가 가상 함수인지 역 체크 가능 ( 코드 참조)
review
다중 상속과 다형성 : Overloading, Override를 배웠다.
C++에서는 다중 상속을 허용한다는 점이 새로웠다.
파일 분할할 때 구현부에서 누구의 함수의 인지 표시해주는 것과 같은
메커니즘인 것 같다.
누구의 것인지 알 수 없어서 발생하는 모호함 때문에
다중 상속을 쓰지 말라고 하는데
누구의 것인지를 지정해주면 :: 모호함이 없어져서 사용할 수 있었다!
다형성을 배우면서 새로운 개념을 알게 되어서 좋았다.
객체에게 어떤 메시지를 보낸다는 의미는
그 객체의 함수를 호출한다는 의미라는 개념
함수를 호출해서 사용할 때
그 함수를 내가 가지고 와서 사용한다는 생각이었는데,
내가 그 함수로 메시지를 보내는 거였다!
## 체크 포인트
같은 함수를 사용하지만 인자 값에 따라 다르게 호출되도록 하는
오버 로딩
상속관계에서 부모의 가상 함수를 재정의 - 들어오는 타입에 맞춰 호출되도록
오버 라이딩
일반 함수는 담는 데이터 타입 - 그릇-의 함수를 호출해서 준다.
가상 함수는 들어온 데이터 타입에 맞는 것 그릇 안에서 찾아서 호출해준다.
'Back-end > C++' 카테고리의 다른 글
22. 03. 31 - 몬스터 전투 실습 ( 오버로딩을 통한 다형성, 파일분할 ) (0) | 2022.04.09 |
---|---|
22. 03. 30 - 가상 함수, 함수 포인터, 함수 배열 (0) | 2022.04.07 |
22. 03. 28 - 포함 ( Compositon, Aggregation ) (0) | 2022.04.06 |
22. 03. 25 - 상속( 접근 제어자, 업 캐스팅, 다운 캐스팅 ) (0) | 2022.04.03 |
22. 03. 24 - 상속(특수화) : 동물 육성 게임, string 클래스 기능 추가 상속 (0) | 2022.04.02 |