Interface(9) – 인터페이스 매개변수의 다형성 및 캐스팅


자바 로고 이미지

매개변수 다형성도 상속 장에서 탐구한 것입니다.

매개변수 유형이 슈퍼클래스로 선언되면 하위클래스가 매개변수 범위에 인수로 전달될 때 자동 유형 변환이 발생합니다.

인터페이스에도 동일하게 적용됩니다.

파라미터 타입이 인터페이스로 선언된 경우 인터페이스를 구현하는 구현 클래스 적절한 매개변수에 인수로 전달할 수 있습니다.

그리고 이 파라미터의 메소드를 호출하면 각 구현 클래스에서 오버라이드한 메소드가 실행되기 때문에 다른 결과가 호출될 수 있다.

Vehicle이라는 인터페이스를 매개변수로 받는 메소드가 있다면 이를 구현한 Bus 클래스의 인스턴스를 매개변수로 전달할 수 있다.

인스턴스 변수나 새로운 형태로 직접 전달할 수 있겠죠?

이번에는 바로 본론으로 들어가 예제를 살펴보겠습니다.

이것은 기본적으로 run()이라는 추상 메서드가 있는 Vehicle 인터페이스를 사용하는 예입니다.

public interface Vehicle {
	public void run();
}

public class Bus implements Vehicle {
	public void run() {
		System.out.println("Bus runs.");
	}
}

public class Tesla implements Vehicle {
	public void run() {
		System.out.println("Bus runs.");
	}
}

public class Driver {
	public void drive(Vehicle vehicle) {
		vehicle.run();
	}
}

public class ExampleMain {	
	public static void main(String() args) {
		Driver driver = new Driver();
		
		Bus bus = new Bus();
		Tesla tesla = new Tesla();
		
		driver.drive(bus);
		driver.drive(tesla);
	}
}

/* 출력
Bus runs.
Tesla runs.
*/


이제 짐작하셨겠지만 강제 형 변환을 살펴볼 시간입니다.

상속 대 캐스팅 장에서 살펴보았습니다.

위에서 설명한 것처럼 구현 클래스가 자식 클래스의 위치가 되므로 자동 유형 변환도 인터페이스에서 발생합니다.

즉, 인터페이스 타입으로 변경됩니다.

그러면 상속받은 클래스와 마찬가지로 구현 클래스가 자동으로 인터페이스 타입으로 변환된 후 구현 클래스의 네이티브 메서드를 사용할 수 없게 된다.

인터페이스에 선언된 추상 메서드만 사용할 수 있습니다.

예를 들어 인터페이스가 3개의 추상 메서드를 선언하고 구현 클래스가 이러한 3개의 추상 메서드의 재정의를 선언하고 2개의 추가 고유 메서드가 있다고 가정합니다.

인터페이스 타입으로 자동 전환된 후에는 인터페이스 타입으로 전환되었기 때문에 3개의 추상 메서드만 사용할 수 있습니다.

이 경우 추가로 선언된 2개의 구현 클래스별 메서드는 사용할 수 없습니다.

그러나 변수에 대해 이 두 메서드를 사용해야 하는 순간이 오면 캐스팅을 통해 강제 형식 변환을 수행하고 다시 구현 클래스의 형식으로 변환할 수 있습니다.

구현클래스 변수 = (구현클래스) 인터페이스변수;
Bus bus = (Bus) vehicle;

위에서 사용한 Vehicle 인터페이스와 Bus 구현 클래스를 약간 수정하여 예제를 살펴보겠습니다.

public interface Vehicle {
	public void run();
}

public class Bus implements Vehicle {
	@Override
	public void run() {
		System.out.println("Bus runs.");
	}
	
	public void checkTicket() {
		System.out.println("Ticket Approved.");
	}
}

public class ExampleMain {	
	public static void main(String() args) {
		Vehicle vehicle = new Bus();
		vehicle.run();
		
		Bus newBus = (Bus) vehicle;
		newBus.run();
		newBus.checkTicket();
	}
}

/* 출력
Bus runs.
Bus runs.
Ticket Approved.
*/