java 기본 유형의 데이터드러럼 객체 참조변수의 경우에도 형변환(Casting)이
이 이루어진다.
서로 다른 클래스 유형으로부터 나온 객체 참조변수들 간의 대입에는 일정한
규칙이 있다.
Parent parent = new Child();
위의 대입연산에서 왼쪽 항(Parent)과 오른쪽항(Child)의 객체 유형이 서로
다른 경우, 두 유형이 서로 상속 관계에 있고 왼쪽 객체(Parent)가 오른쪽 객체
(Child)의 상위 클래스인 경우에만 암묵적인 형 변환이 일어난다.
하위 클래스에서 상위클래스 유형으로 할당하는 것은 가능하나
그 반대의 경우에는 명시적 형 변환을 해야 한다.
A a1 = new B();
A a2 = new X();
----------------
A a3 = new C();
A a4 = new Y();
-----------------
B b1 = new C();
X x1 = new Y();
------------------
C c = new C();
B b2 = c;
------------------
Y y = new Y();
X x2 = y;
암묵적 형변환은 부모를 상속받은 자식 객체의 기능을 부모에게 물려받은
기능만 사용하도록 제한한다.
그러므로 암묵적 형변환이 발생하면 오버라이드된 기능만 사용가능하고,
추가적으로 구현한 기능은 사용할 수 없다.
주의할 점은 기능의 제한이지 기능의 변경은 아니라는 것이다.
상속관계의 객체를 부모 형태로 변환하면 클래스의 종류를 구분하지 않고,
일관된 기능을 호출 할 수 있다.
객체가 상위클래스 형태로 형변환 되더라도 Override된 자신의 기능은
잃지 않는다.
Unit u1 = army;
Unit u2 = navy;
Unit u3 = airforce;
u1.attack();
u2.attack();
u3.attack();
하지만, 추가적으로 구현한 기능은 사용할 수 없게 되므로 원래의 기능을 다시
사용할 수 있는 방법이 필요해졌다.
부모 클래스의 객체를 자식 클래스 형태로 변환하는 것
형 변환을 위해서는 다음과 같이 변환할 클래스 이름을 명시적으로 지정해
주어야 한다.
ChildClass child = (ChildClass) parent;
객체가 최초 생성될 때 자식 클래스 형태로 생성되고, 부모 형태로 암묵적
형변환이 된 상태를 다시 원래의 자식 클래스 형태로 되돌릴 경우에만 가능하다.
ChildClass child1 = new ChildClass();
ParentClass Parent = child1; // 암묵적 형변환
ChildClass child2 = (ChildClass)parent; // 명시적 형변환
가능한 경우
Army army1 = new Army();
Unit u = army1;
Army army2 = (Army)u;
가능한 경우
Unit u = new Navy();
Navy navy = (Navy)u;
최초 객체 생성이 부모 형태로 만들어진 경우 불가능하다.
Unit u = new Unit();
Army army = (Army)u;
최초 생성된 것과 다른 형식으로 변환하는 것은 불가능 하다.
Army army = new Army();
Unit u = army;
Navy navy = (Navy)u;
위의 두 경우 모두 문법적인 오류는 없기 때문에, 이클립스에서는 에러를
검출하지 못한다. 하지만 프로그램을 실행시켰을 경우에는 에러가 발생한다.
일반 데이터 타입의 배열과 동일한 개념으로, 같은 클래스의 객체 여러개를
그룹화 할 수 있다.
int[] data = new int[3];
Army[] data = new Army[3];
각 경우에 대한 배열의 요소 할당 처리
-> 일반 데이터 형은 단순히 값을 대입하지만, 객체 배열은
'new'를 사용하여 객체를 할당한다.
data[0] = 1;
data[1] = 2;
...
---------------------
data[0] = new Army();
data[1] = new Army();
...
배열의 생성이 부모 클래스로 지정되었을 경우, 모든 자식 클래스의 객체들은
그 배열에 포함될 수 있다.
Unit[] unit = new Unit[3];
// 배열의요소 할당 과정에서 암묵적 형변환이 이루어진다.
unit[0] = new Army();
unit[1] = new Navy();
unit[2] = new AirForce();
일괄 처리가 가능하다.
서로 다른 객체를 부모 형태의 배열에 담기게 되면, 반복문으로 일괄 처리가
가능하다.
이 때 배열의 각 요소를 통해 사용하는 메서드가 Override 되어있을 경우,
부모의 메서드가 아니라 자신이 재정의한 기능을 뜻한다.
for ( int i =0; i < unit.length; i++ ){
unit[i].attack();
}
배열의 각 요소가 확장한 기능을 사용하기 위해서는 원래의 클래스 형태로
명시적 형변환이 이루어 져야 한다.
하지만 반복적으로 처리되는 과정에서 몇 번째 요소가 어떤 클래스에서
최초 생성되었는지를 판단하기란 쉽지 않다.
instanceof 연산자
-> 어떤 객체에 대한 출처를 판단하여 boolean 형으로 결과를 반환한다.
if( unit[0] intanceof Army ){
Army temp = (Army)unit[0];
}