코드일기장

[Java] 참조변수의 형변환 본문

Java/OOP

[Java] 참조변수의 형변환

won_hyeok2 2022. 3. 15. 22:11

 

 

 

 

- 사용할 수 있는 멤버의 개수를 조절하는 것

 

 

형변환이 가능할 때는 

조상 자손 관계의 참조 변수는 서로 형 변환 가능 (서로 상속관계에 있는 타입 간의 형 변환만 가능)

 

자손 타입에서 조상 타입으로 형변환하는 경우, 형변환 생략 가능

 

자손 타입-> 조상 타입 (Up-casting) :형변환 생략 가능

조상 타입-> 자손 타입(Down-casting): 형변환 생략 불가

 

 

public class OOP {
	public static void main(String[] args) {
		dog d = new dog();
		animals a = (animals)d;  	//Up-casting조상인 animals타입으로 형변환 (생략가능) animals a= d
		dog d2 = (dog)a;		//Down-casting자손인 dog타입으로 형변환(생략불가)
		//cat c =(cat)d;			//error 상속관계 아닌 클래스 간의 형변환 불가
	
	}
}

class animals{
	int size;
	
	void move() {
		System.out.println("움직이는 중...");
	}
	
	String habit(String str) {
		return str;
	}
}

class dog extends animals{
	String name="dog";
}


class cat extends animals{
	String name="cat";
}

 

animals의 멤버는 3개 

dog와 cat은 상속받은 멤버 3개+1개 =4개이다.

 

위에 코드에 참조변수 a를 형변환된 참조변수 d를 대입하려고 할 땐(Up castion) 형변환 연산자를 생략 가능하다.

반대로 조상 참조변수를 자손타입으로 형변환하여 대입하는 것은 생략이 불가능해진다.

 

위에 참조변수 a, d, d2는 모두 같은 객체 주소를 가리킨다.

 

조상타입->자손타입으로 형변환(Down-castion) 안 되는 이유는 

자손(4개)-> 조상(3개) 멤버의 개수를 줄이는 것은 안전한 형변환이므로 형변환 연산자 생략 가능.  -Up casting

조상(3개)-> 자손(4개) 멤버의 개수를 늘리는 것은 불안정한 형변환이므로 형변환 연산자 생략이 불가능한다.  -Down castion

 

 

 

public class Main {
	public static void main(String[] args) {
		Parent p = null;
		Child c1 = new Child();
		Child c2 = null;
		
		c1.callAge();
		p = c1;
		//p.callAge()  Parent에는 callAge 메서드가 없다.
		c2=(Child)p;
		c2.callAge();
	}
	
}

class Parent{
	String name;
	String address;
	
	void callName() {
		System.out.println(name);
	}
}

class Child extends Parent{
	int age=20;
	
	void callAge() {
		System.out.println(age);
	}
}
20
20

 

 

 

 

package pack;
public class Main {
	public static void main(String[] args) {
		Parent p = new Parent();
		Child c = (Child)p;
		c.callAge();
	}
	
}

class Parent{
	String name;
	String address;
	
	void callName() {
		System.out.println(name);
	}
}

class Child extends Parent{
	int age=20;
	
	void callAge() {
		System.out.println(age);
	}
}

위 코드는 컴파일되고 정상적인 코드인듯 하지만, 예외가 발생한다.

 

Exception in thread "main" java.lang.ClassCastException: class pack.Parent cannot be cast to class pack.Child (pack.Parent and pack.Child are in unnamed module of loader 'app')
	at pack.Main.main(Main.java:5)

 

위 예외는 ClassCastExcetion이다.  Parent는 Child로 형변환 불가능하다 하다. (실행 에러)

 

컴파일러는 Parent를 객체를 객체화 할 때 멤버의 개수는 생각 안 한다. 

형변환 후 Child 객체를 가리키는 참조변수 c로 Child의 멤버를 가르쳐보니

 

Parent 객체를 가르키는 참조변수 p는 멤버가 3개인 객체인 것이다.

 

c로 callAge() 메서드를 호출해보니 안된다.

c는 이미 p와 같은 객체 주소를 입력받았다. p의 객체는 Parent클래스로 멤버가 3개이다. 즉, Child 클래스의 age iv와 callAge 메서드는 호출과 접근을 못하는 것이다.

 

 

컴파일러는 참조변수 형변환 조건인 부모 자식 관계만 true일 시 무작정 컴파일시켜준다. 

그러한 이유로 위 코드는 컴파일은 가능하지만, 실행(호출)은 안 되는 것이다.

 

 

 

 

다양한 방법으로 예외를 발생 안 시킬 수 있다.

Parent p = new Parent();
Child c2 = new Child();
p=c2;
Child c = (Child) p;
c.callAge();

 

 

'Java > OOP' 카테고리의 다른 글

[Java/OOP] 추상클래스 (abstract class)  (0) 2022.04.29
[Java] instanceof 연산자  (0) 2022.03.20
[Java] 다형성  (0) 2022.03.04
[Java] 접근 제어자 (access modifier)  (0) 2022.02.20
[Java] static, final, abstract의 정의  (0) 2022.02.18
Comments