07-42.1 클래스 형변환
- 기본형의 형을 바꾼 것처럼 클래스형의 형도 바꿀 수 있다.
Ex)
Car car = new Van();
- Car를 가리키겠다고 선언한 car형 변수인데 Van 가리키고 있다.
- 묵시적 형변환이 일어나서 오류가 발생하지않는다.
- 클래스는 부모 객체가 항상 더 큰 그릇이라고 생각하면 된다.
- 형변환 하는 이유는?
-> 부모가 자식을 가리킬 수 있으나 부모가 알고 있는 메서드 까지만 접근할 수 있기 때문이다.
-> 이 때, 형변환으로 객체가 가진 모든 부분을 사용한다.
(1) 묵시적(암묵적) 형변환: 큰 그릇에 작은 그릇의 값을 담는 경우
- 오류가 발생하지 않는다.
(2) 명시적 형변환: 작은 그릇에 큰 그릇의 값을 담는 경우
- 큰 그릇에 들어있는 값에 따라서 실행 시점에 오류가 발생할 수 있다.
- 따라서, 프로그래머에세 명시적으로 형변환할 것을 요구한다.
07-42.2 형변환 예제
(1) Car클래스에 run메서드 추가
<hide/>
package javaStudy;
public class Car{
public void run() {
System.out.println("Car의 run메서드");
}
}
(2) Car클래스를 상속 받는 Van클래스
<hide/>
package javaStudy;
public class Van extends Car {
public void ppangppang() {
System.out.println("빵빵");
}
}
- Van에는 Car에 없는 ppangppang 메서드가 있다.
- 둘의 상속 관계가 있으니 Van객체를 Car형의 참조 변수로 참조할 수 있다.
- 부모 타입 으로 자식 객체를 참조하게 되면 부조가 가진 메서드만 이용 가능하다.
(3) VanExam 에서 실행한다.
<hide/>
package javaStudy;
public class VanExam {
public static void main(String[] args) {
Car c = new Van();
c.run();
}
}
Note) 실행결과: Car의 run 메서드
- Car c = new Van(); 을 보면 Car형 변수 c가 Van의 인스턴스를 가리킨다.
- 묵시적 형변환이 일어난다.
- 객체들 사이에상속이 일어나면 부모형 그릇에 그 부모를 상속 받은 자식들, 그 자식의 자식들도 모두 담을 수 있다.
- 기본 자료형과 다르게 참조(레퍼런스 ) 자료형은 실제 값이 아니라 주소를 가지므로 '가리킨다'고 표현 한다.
- 부모 타입인 Car라는 형으로 자식 타입인 Van을 가리킬 수 있다는 뜻이다.
- Car형의 레퍼런스 변수 c는 Car가 가진 run이라는 메서드를 사용하는데 문제가 없다.
- Car형 이기는 하지만 실제로 생성된 객체는Van이다.(new Van)
- Van에는 run외에도 ppangppang 메서드를 사용할 수 있다.
(4)
<hide/>
package javaStudy;
public class VanExam {
public static void main(String[] args) {
Car c = new Van();
c.run();
// c.ppangppang();
Van van = (Van)c;
van.run();
van.ppangppang();
}
}
- c뒤에 마침표를 찍으면 사용 가능한 메서드가 많지만 ppangppang은 나오지 않는다
- 또, 실행하면 에러가 난다.
- 부모 타입으로 자식을 가리킬 수는 있지만 부모 타입으로 자식을
- Van객체에는 ppangppang메서드가 있다.
- 하지만, 부모 타입으로 가리키고 있어서 ppangppang을 사용할 수 없다.
- 이럴 때 형변환하면 이 기능을 사용할 수 있다.
- Car c = new Van() : Car타입(부모)이 Van타입(자식)을 가리키고 있다.
-> 아무 문제 없다. (Car는 Van보다 상위 개념)
- Van van = c : Van타입으로 묶어서 c를 가리키려고 하면 에러가 난다.
- c는 Car형이기 때문에 그보다 작은 Van형이 가리킬 수는 없다.
- Car에 어떤 차가 올지 알 수 없다.
- 기본형 변수에서 큰 그릇에 있는 것을 작은 그릇으로 옮길 때, 그릇의 크기를 알면 강제로 형변환 할 수 있다.
-> Van van = (Van)c : c앞에 Van형으로 형변환한다.
Note) 실행 결과
- Car가 참조하는 변수가 원래 Van이기 때문에 형변환이 가능하다.
- 실제로 생성된 것이 Van이었기 때문에 Van으로 타입을 바꿀 수 있다.
07-42.3 클래스 형변환 실습
Ex 1) Car클래스는 gas라는 필드를 가진다. Car클래스를 상속받은 Suv, Track, Bus 클래스가 있다.
GasStation 클래스에서는 fill(주유하다)라는 메서드가 있다. 총 3종류의 fill 메서드가 오버로딩되어 있다. 각각 Car, Suv, Track, Bus 클래스를 한번씩 살피고 GasStation코드를 살핀 후 결과를 확인하라.
<hide/>
package javaStudy;
public class Suv extends Car {
public Suv(String name) {
super.name = name;
}
}
<hide/>
package javaStudy;
public class Truck extends Car {
public Truck(String name) {
super.name = name;
}
}
<hide/>
package javaStudy;
public class Bus extends Car {
public Bus(String name) {
super.name = name;
}
}
<hide/>
package javaStudy;
public class Car{
public int gas;
public String name;
}
<hide/>
package javaStudy;
public class GasStation {
public static void main(String[] args) {
GasStation gasStation = new GasStation();
Suv suv = new Suv("suv");
Truck truck = new Truck("Truck");
Bus bus = new Bus("Bus");
gasStation.fill(suv);
gasStation.fill(truck);
gasStation.fill(bus);
}
public void fill(Car car) {
System.out.println( car.name + "에 기름을 넣습니다." );
car.gas += 10;
System.out.println("기름이 " + car.gas + "리터 들어있습니다." );
}
}
Note) 출력 결과
- public void fill(Car car) : 메서드의 매개변수로 Car 타입만 들어가야 한다.
- 그런데 실제 사용하는 코드를 보면 fill(suv)처럼 Suv타입도 들어가고
- Car타입이 아닌데도 해당 메서드를 에러 없이 사용한다.
- Suv, Truck, Bus 타입이 Car타입으로 형변환 돼서 fill 메서드를 실행한다.
- 하위타입을 상위타입으로 형변환 하면 묵시적 형변환이 일어난다.
- fill메서드에 인자로 Car의 하위 클래스들이 들어가면 해당 메서드 안에서 사용될 때
- Car타입으로 형변환이 일어난 상태이므로 하위 클래스에서 추가로 정의한 부분에는 접근할 수 없다.
07-42.4 클래스 형변환 실습
Ex 2) Car를 상속 받은 Bus클래스에는 announcements 메서드가 있다. 하지만 타입이 Car인 ㄱ경우에는
announcemants 메서드가 있어도 사용할 수 없다. 다음 코드에서 car.announcements();에 에러가 난다.
에러가 발생하지 않도록 announcements(); 메서드를 사용하도록 코드 수정하라.
<hide/>
package javaStudy;
public class CarExam {
public static void main(String[] args) {
Car car = new Bus();
car.run();
//오답 car.announcements();
Bus bus = null;
bus = (Bus) car;
bus.announcements();
}
}
<hide/>
package javaStudy;
public class Car{
public void run() {
System.out.println("차가 달립니다.");
}
}
<hide/>
package javaStudy;
public class Bus extends Car {
public void announcements() {
System.out.println("안내방송을 합니다.");
}
}
Note) 출력 결과
- Car를 상속받은 Bus클래스에는 announcaments() 메서드가 있다.
- 하지만 타입이 Car형이므로 announcaments() 메서드를 사용할 수 없다.
- 따라서 car.announcaments(); 에서 오류가 발생한다.
- 부모 타입으로 자식 타입을 사용할 수는 있으나 타입이 부모 타입일 경우에 자식이 추가로 정의한 메서드에 접근할 수 없다.
- 이 때 메서드를 사용하기 위해 Car타입을 Bus 타입으로 형변환 해야한다.
- 하위 타입을 상위 타입으로 형변환 할 때는 묵시적 형변화 일어난다.
- 상위 차입을 하위 타입으로 형변환 하는 경우에는 반드시 명시적 형변환을 해줘야한다.
'Java > 모두의 자바' 카테고리의 다른 글
Chapter 08-45 인터페이스의 default 메서드 (0) | 2022.02.11 |
---|---|
Chapter 08-43 인터페이스 만들기 (0) | 2022.02.09 |
Chapter 07-41 오버라이딩(Overriding) (0) | 2022.02.08 |
Chapter 07-40 super과 부모 생성자 (0) | 2022.02.08 |
Chapter 07-39 추상 클래스 (0) | 2022.02.08 |