Lang/JAVA

A bb = new C();

finepiz 2021. 12. 26. 13:18

A bb = new C();

C cc = new C();

이게 뭐야?

 

===========================

해결 (1)

->

https://www.opentutorials.org/module/516/6127

 

다형성 - Java

이번 시간에는 다형성(Polymorphism)이라는 주제에 대해서 알아보자. 다형성이란 하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다. 키보드의 키를 통해서 비유

www.opentutorials.org

여기 내용에

[클래스와 다형성] 중

A obj = new B();클래스 B는 클래스 A를 상속하고 있는 경우, 클래스 B는 클래스 A를 데이터 형으로 삼을 수 있다.

 

*다형성이란 하나의 메소드나 클래스가 있을 때이것들이 다양한 방법으로 동작하는 것

*polymorphism(다형성) : 여러 개의 형태를 갖는다

*철학적인 느낌을 자아내는 용어. 잘 모를 땐 뒷 내용을 보고 일단 구체적으로 보려고 하자

 

이 코드에서

obj.x();는 실행이되고

obj.y();는 실행되지 않는데

클래스 B는 메소드 y를 갖고 있지만 y가 마치 존재하지 않는 것처럼 실행되지 않는다.

클래스 B의 데이터 형을 클래스 A로 하면 클래스 B는 마치 클래스 A인것처럼 동작하게 된다.

클래스 B를 사용하는 입장에서는 클래스 B를 클래스 A인것처럼 사용하면 된다

 

이건 클래스 B가 오버라이딩 하고 있는 코드

obj.x()의 실행결과는 B.X이다 : 오버라이딩 하고 있는 메소드가 실행된다

앞의 예에선 클래스 B가 A화 됐지만

클래스 B에서 정의된 메소드가 실행 된걸 보면 클래스 B의 기본적인 성질은 그대로 간직하고 있는것

 

정리하면

클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 했을 때

클래스 A에 존재하는 맴버만이 클래스 B의 맴버가 된다.

동시에 클래스 B에서 오버라이딩한 맴버의 동작방식은 그대로 유지한다.

클래스 A의 멤버만 쓸 수 있는데, 그게 오버라이딩 됐다면 그걸로 바뀐다.

 

 

그래서 이걸 어디에 쓰나요?

▽여기서부터 내가 씀

이걸 보시면요

메인에

execute(c1);

execute(c2);

라고 했는데 주목할 부분은 c1 c2가 다른 클래스의 객체라는 거죠

근데? 참조변수는 같지 않습니까? public static void execute(Calculator cal) { }  <-- 이 부분!

그래서 execute()의 인자로 다른게 들어왔는데 그것에 대해 같은 행동을 할 수가 있습니다

 

□여기서부터 생코가 씀

메소드 execute 입장에서는

매개변수로 전달된 값이 Calculator이거나 그 자식이라면(▽그럼 부모 타입을 쓸 수 있어, 그리고 그 타입은 부모의 메소드를 무조건 갖고 있지 동작은 다르겠지만) 메소드 run을 가지고 있다는 것을 보장 받을 수 있게 되는 것

이 맥락에서의 다형성이란

하나의 클래스(Calculator)가

다양한 동작 방법(ClaculatorDecoPlus, ClaculatorDecoMinus)을 가지고 있는데

이것을 다형성이라고 할 수 있겠다. 

 

===========================

해결 (2)

저게 무슨 원리로 저렇게 되는지가 궁금해

->https://m.blog.naver.com/honnynoop/22805940

 

메모리 구조 기본 (1)-섹션 143

다음은 섹션 143의 내용입니다. 내용을 정리했습니다. 자바의 메모리는 크게 3부분으로 나눌 수 있다(9개 ...

blog.naver.com

(1)A a2 = new A();

 : 자식 타입으로 자식을 new해도

->자식의 설계도+부모의 설계도가 스태틱영역에 올라가

->힙 영역에는 자식객체가 생성되는데 부모인 객체도 생성된다.

->a2는 부모의 주소를 참조해 그냥 무조건 부모를 가리키고 있네

 : 스태틱 영역(설계도 영역)에 올라간 타입의 메소드만 호출할 수 있다

 

===

(2)

다형성을 이해해야 한다.

부모에게 문을 열다라는 메소드가 있으면 자식의 종류에 따라 문을 열다는 다양한 형태를 가질 수 있다.

어떤 객체를 밑에 달고 있으면 비행기의 문을 열고

어떤 객체를 밑에 달고 있으면 방의 문을 열고

부모의 메소드로 자식의 메소드를 호출할 수가 있는 것.(오버라이딩 했다면)

 

다형성이 발생되는 원인 3가지

- 부모의 타입으로 자식의 객체를 생성할 수 있음

- 부모의 타입으로 자식의 객체를 받을 수 있음(메소드 인자 얘기겠지?)

- 부모이 메소드로 자식의 메소드를 호출할 수 있음

Parent a3 = new A();

는 부모의 타입으로 자식의 객체를 생성하는 경우인데, 

- 설계도 영역에는 Parent타입이 올라감

- ▽오버라이딩이 가능한 이유는? 이 그림에선 안나와. 저 세모는 오버라이딩 메소드가 아니야 저~밑에 있어

- 힙에는 부모 + 자식 객체가 올라감. 메모리의 특징에 의해 a3는 원, 네모의 메소드만 사용할 수 있어.

 : 자식에 있는 세모 메소드를 사용하고 싶으면?? 설계도를 변경해서 A타입으로 변경시키면 된다

->A a4 = (A) a3;

- a3는 위에서 만들었던 거고, 그걸 캐스팅해서 A타입 객체에 넣음

- 설계도만 A(A+Parent)타입으로 변경하는 거고 힙의 객체는 변경되지 않는다.

- 이렇게 캐스팅하면 설계도 영역에 A+Parent의 메소드를 모두 호출해서 사용할 수 있음. a4.세모()도 가능

 

===

A a5 = new A();

Parent a6 = a5

 : ▽반대의 경우는 캐스팅 안해도 되는군

이렇게 되면 a5와 a6의 메모리에 올라간 설계도와 인스턴스가 다르다.

a6은 설계도 영역에있는 Parent 타입 메소드만 사용할 수 있다.

아래 그림의 a6.○ a6.□ 가 호출할 수 있는 메소드다

 

===

Parent d8 = new D();

오버라이딩 했을 경우,

설계도가 부모거여도, 자식에도 똑같은게 있으면 거기로 가네,

참조는 항상 부모라서 이 모든게 가능하군