다형성
상속은 같은 종류의 하위 클래스를 만드는 기술이고, 인터페이스는 사용 방법이 동일한 클래스를 만드는 기술이라는 개념상의 차이는 있지만 둘 다 다형성을 구현하는 방법은 비슷한, 모두 재정의와 타입 변환 기능을 제공하기 때문.
자동 타입 변환(promotion)
구현 객체가 인터페이스 타입으로 변환되는 것으로, 자동 타입 변환은 프로그램 실행 도중에 자동적으로 타입 변환이 일어나는 것을 말함.
인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환할 수 있음.
자동 타입 변환을 이용하면 필드의 다형성과 매개 변수의 다형성을 구현할 수 있는데, 필드와 매개 변수의 타입을 인터페이스로 선언하면 다양한 구형 객체를 대입해서 실행 결과를 다양하게 만들 수 있음.
필드의 다형성
// 인터페이스
package sec02.exam01;
public interface Tire {
public void roll(); // roll() 메소드 호출 방법 설명
}
// 구현 클래스
package sec02.exam01;
public class HankookTire implements Tire {
@Override // Tire 인터페이스 구현
public void roll() {
System.out.println("한국 타이어가 굴러갑니다.");
}
}
// 구현 클래스
package sec02.exam01;
public class KumhoTire implements Tire {
@Override // Tire 인터페이스 구현
public void roll() {
System.out.println("금호 타이어가 굴러갑니다.");
}
}
// 필드 다형성
package sec02.exam01;
public class Car {
// 인터페이스 타입 필드 선언과 초기 구현 객체 대입
Tire frontLeftTire = new HankookTire();
Tire frontRightTire = new HankookTire();
Tire backLeftTire = new HankookTire();
Tire backRightTire = new HankookTire();
void run() {
// 인터페이스에서 설명된 roll() 메소드 호출
frontLeftTire.roll();
frontRightTire.roll();
backLeftTire.roll();
backRightTire.roll();
}
}
// 필드 다형성 테스트
package sec02.exam01;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.run();
myCar.frontLeftTire = new KumhoTire();
myCar.frontRightTire = new KumhoTire();
myCar.run();
}
}
매개 변수의 다형성
// 매개 변수의 인터페이스화
package sec02.exam02;
public class Driver {
public void drive(Vehicle vehicle) {
vehicle.run();
}
}
// 인터페이스
package sec02.exam02;
public interface Vehicle {
public void run();
}
// 구현 클래스
package sec02.exam02;
public class Bus implements Vehicle {
@Override
public void run() {
System.out.println("버스가 달립니다.");
}
}
// 구현 클래스
package sec02.exam02;
public class Taxi implements Vehicle {
@Override
public void run() {
System.out.println("택시가 달립니다.");
}
}
// 매개 변수의 다형성 테스트
package sec02.exam02;
public class DriverExample {
public static void main(String[] args) {
Driver driver = new Driver();
Bus bus = new Bus();
Taxi taxi = new Taxi();
driver.drive(bus); // 자동 타입 변환: Vehicle vehicle = bus;
driver.drive(taxi); // 자동 타입 변환: Vehicle vehicle = taxi;
}
}
강제 타입 변환(casting)
구현 클래스에 선언된 필드와 메소드를 사용해야 할 경우, 강제 타입 변환을 해서 다시 구현 클래스 타입으로 변환한 다음, 구현 클래스의 필드와 메소드를 사용할 수 있음.
// 인터페이스
package sec02.exam03;
public interface Vehicle {
public void run();
}
// 구현 클래스
package sec02.exam03;
public class Bus implements Vehicle {
@Override
public void run() {
System.out.println("버스가 달립니다.");
}
public void checkFare() {
System.out.println("승차요금을 체크합니다.");
}
}
// 강제 타입
package sec02.exam03;
public class VehicleExample {
public static void main(String[] args) {
Vehicle vehicle = new Bus();
vehicle.run();
//vehicle.checkFare(); vehicle 인터페이스에는 checkFare()가 없음.
Bus bus = (Bus) vehicle; // 강제 타입 변환
bus.run();
bus.checkFare(); // Bus클래스에는 checkFare()가 있음.
}
}
객체 타입 확인
인터페이스 타입으로 자동 타입 변환된 매개값을 메소드 내에서 다시 구현 클래스 타입으로 강제 타입 변환해야 한다면 반드시 매개값이 어떤 객체인지 instanceof 연산자로 확인하고 안전하게 강제 타입 변환을 해야함.
// 객체 타입 확인
package sec02.exam04;
public class Driver {
public void drive(Vehicle vehicle) { // Bus 객체, Taxi 객체
if(vehicle instanceof Bus) { // vehicle 매개 변수가 참조하는 객체가 Bus인지 조사
Bus bus = (Bus) vehicle; // Bus 객체일 경우 안전하게 강제 타입 변환
bus.checkFare(); // Bus 타입으로 강제 타입 변환을 하는 이유
}
vehicle.run();
}
}
// 객체 타입 확인
package sec02.exam04;
public class DriverExample {
public static void main(String[] args) {
Driver driver = new Driver();
Bus bus = new Bus();
Taxi taxi = new Taxi();
driver.drive(bus);
driver.drive(taxi);
}
}
// 실행 결과
// 승차요금을 체크합니다.
// 버스가 달립니다.
// 택시가 달립니다.
🔘 자동 타입 변환: 구현 객체가 인터페이스 변수에 대입되는 것을 말함.
🔘 다형성: 상속은 같은 종류의 하위 클래스를 만드는 기술이고, 인터페이스는 사용 방법이 동일한 클래스를 만드는 기술이라는 개념상의 차이는 있지만 둘 다 다형성을 구현하는 방법은 비슷한, 모두 재정의와 타입 변환 기능을 제공하기 때문.
🔘 강제 타입 변환: 인터페이스에 대입된 구현 객체를 다시 원래 구현 클래스 타입으로 변환하는 것을 말함.
🔘 instanceof: 강제 타입 변환을 하기 전에 변환이 가능한지 조사할 때 사용하며, 상속에서는 자식 클래스 타입인지, 인터페이스에서는 구현 클래스 타입인지를 확인할 때 사용함.
🔘 인터페이스 상속: 클래스는 다중 상속을 허용하지 않지만, 인터페이스는 다중 상속을 허용함. extends 키워드 뒤에 상위 인터페이스가 올 수 있음.
'Java' 카테고리의 다른 글
| [Java] 익명 객체 (0) | 2025.11.15 |
|---|---|
| [Java] 중첩 클래스와 중첩 인터페이스 (0) | 2025.11.15 |
| [Java] 인터페이스 (0) | 2025.11.14 |
| [Java] 추상 클래스 (0) | 2025.11.14 |
| [Java] 타입 변환과 다형성 (0) | 2025.11.12 |