본문 바로가기
study/JAVA

JAVA Casting

by stilinski 2022. 4. 5.
728x90
  • 객체형변환 - 참조데이터타입
    • 기본적으로는 안되지만 상속관계(is a)일때 가능.
    • 반드시 업캐스팅이 발생된 후 다운캐스팅을 할 수 있다.
      • 업캐스팅(up-casting) : 부모객체로 자식객체를 참조할 수 있도록 형 변환하는 기술
      • 다운 캐스팅(down-casting) : 업캐스팅을 다시 원상 복구해주는 형 변환하는 기술


독립적인 참조 데이터 타입(객체)은 형 변환이 안된다

Up-casting

자식을 부모로 변환은 가능한데
부모를 자식으로 변환은 불가능

부모로 형 변환하면 자식에 있는 메서드 사용 안됨

p=c
P에 c의 주소가 할당됨

그러나 p에 있는 거만 호출 가능(부모 클래스에 있는 거)
오버라이딩된거는 오버 라이딩된 거로 호출됨










부모를 자식으로 형 변환 사실 가능

down-casting

단 원래부터 자식이었던 것이 부모 타입이 된 경우에만 부모를 자식으로 다운 캐스팅 가능.

다운 캐스팅하면 원래 자식 클래스에 있는 기능들 쓸 수 있게 됨.
call은 차일드에만 있는 메서드



  • 부모 타입(형 변환 한 번도 안 한)을 자식 타입으로 변환 안 되는 이유

생각해보면 간단함.

자식이 부모 클래스를 상속받으면 대충 이런 형태임
자식 클래스는 부모 꺼를 받아서 더 커짐.
즉 부모는 자식의 일부분이 됨. 자식이 부모 타입이 되는 건 부모가 자식의 일부분이니 가능함.
그러나 부모는 작아서 안됨. 자식에게는 부모에게 없는 자식만의 고유한 특성이 있음(필드나 메서드) 자식이 부모를 상속받는다고 해도 부모 꺼를 자기가 받는 거지 지꺼를 부모한테 주는 거는 아님. 부모는 자식에게 있는 것들이 없는 상태인데 당연히 자식 타입으로 형 변환 안됨.



다형성

  1. 사전적 의미는 여러 가지 형태를 가질 수 있는 능력을 의미
  2. 자바에서는 한 타입의 참조 변수로 여러 타입의 객체를 참조하는 기술이다. 예를 들면, 하나의 타입으로 상속관계에 있는 여러 객체를 다루는 기술이다.

void add(double a, double b){}
add(1,2);
add(1.2f,1.5f);
add(2.5,3.5)
void add(Parent a, Parent b){} // 상속관계면 3개의 타입 매개변수로 받기 가능
void add(Child a, Child b){}
void add(Sun a, Sun b){}
add(new Parent(), new Parent());
add(new Child(), new Child()); Parent a = new Child();
add(new Sun(), new Sun()); Parent a = new Sun();


바인딩(binding)

: 메서드 호출을 실제 메서드의 몸체와 연결하는 기술이다.
정적 바인딩(static binding): 컴파일 단계에서 어떤 클래스의 어떤 메서드가 호출되는지 연결하는 기술
동적 바인딩(dynamic binding): 실행단계에서 어떤 클래스의 어떤 메서드가 호출되는지 연결하는 기술

캐스팅은 동적 바인딩이다.










사실 우리는 계속 업 캐스팅을 사용 중

Object는 저기 모든 타입의 상위 클래스.
그러므로 매개변수를 오브젝트 타입으로 받으면 거진 모든 데이터 타입 인자로 넣기 가능. <= 업 캐스팅 발생




업 캐스팅 다운캐스팅 활용

업캐스팅

gtv와 samsungtv클래스의 공통적인 기능을 구현하는 메서드들이 있음.
그걸 homeTV로 뺌.
그래서 엘지랑 삼성은 홈 티브이를 상속받고, 그 결과로 process메서드의 인자값인 홈티비 타입으로 넣기가 가능해짐. (부모: 홈티비 자식: 삼성, 엘지)
그러면 업 캐스팅이 일어남.

lg는 홈 티브이 타입이 되기 때문에 lg에 있는 고유한 메서드를 호출을 못함.
즉, 홈 티브이에 있는 공통된 기능들은 사용 가능하지만 lg와 samsung에 각각 있는 메서드는 호출 못함.
그래서 여기서 다운 캐스팅 필요


다운 캐스팅 실시

instanceof 사용

데이터 타입 판별하는 instance of
객체가 어디 클래스 출신인지 따짐

lg를 다시 lg타입으로 바꿔줌. lg는 원래부터 홈 티브이를 상속받고 있기 때문에 모든 영역의 필드를 사용 가능.




그러면 그냥 lg samsung 각각 원래 다 호출 가능한데 왜 이렇게 하냐 할 수 있음.
근데 둘이 중복되는 메서드들이 있기 때문에 똑같은 코드를 2번 써야 함.
그 코드를 한 번만 쓰고, 그 한 번으로 엘지 삼성이 둘 다 쓸 수 있게 하기 위해서 홈 티브이로 중복되는 코드를 빼줌.
그렇게 하면 엘지랑 삼성 고유의 메서드를 호출하지 못하니, 그게 필요할 때 얘네를 다시 원상 복구함(다운 캐스팅). 그리고 각 메서드 호출하면 됨.
결국 결합도를 낮추기 위한 것

lg를 다시 lg타입으로 바꿔줌. lg는 원래부터 홈 티브이를 상속받고 있기 때문에 모든 영역의 필드를 사용 가능.

메모리에선 무슨 일이?!

업 케스팅

process(lg) ⇒ homeTv타입의 lg
그냥 엘지랑 홈티 비타 입으로 전환된 엘지는 주소는 같다
그러나 사용할 수 있는 범위는 다름~

다운 캐스팅

다시 원상복구
저장된 주소는 같으나 사용할 수 있는 범위가 원상 복구됨

업 캐스팅: 다양한 값을 받아서 처리할 수 있도록(상속관계에만 가능)
다운 캐스팅: 업 캐스팅된 데이터들의 고유의 기능들을 호출하기 위해






지금은 이게 더 복잡해 보이지만 크게 봤을 때 훨씬 효율적이고 이득인 방법인 거 같다.
익숙해지기만 하면 아주 좋은 기능이 될 듯.





instance of 자세히 보기~

객체 instanceof 비교 데이터 타입과 같거나 조상 데이터 타입

객체끼리만 가능~





728x90

댓글