본문 바로가기

Programming/JAVA

인터페이스(9) - 인터페이스 파라미터의 다형성 & Casting

java logo image

 

 

 

파라미터의 다형성 역시, 상속 챕터에서 공부해 본 사항입니다. 만약, 파라미터의 타입이 부모 클래스로 선언되어 있을 경우 해당 파라미터 영역에 자식 클래스를 인자로 전달하게 되면 자동 타입 변환이 발생한다는 점을 활용하였죠.

 

인터페이스의 경우도 마찬가지입니다. 파라미터 타입이 인터페이스로 선언되었을 경우, 해당 인터페이스를 구현한 구현 클래스가 해당 파라미터에 인자로 전달될 수 있습니다. 그리고, 이 파라미터의 메서드를 호출하게 되면 각 구현 클래스가 오버라이드 한 메서드가 실행되기 때문에 다양한 결과를 호출할 수 있게 됩니다. 만일 Vehicle이라는 인터페이스를 파라미터로 받는 메서드가 있을 경우, 이를 구현하는 Bus 클래스의 인스턴스가 인자로 전달될 수 있습니다. 인스턴스 변수 혹은 new 형태로 바로 전달할 수 있겠죠? 

 

이번엔 바로 본론으로 들어가서 예제를 살펴보겠습니다. 기본적으로 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.
*/

 

 

 


 

 

 

이제는 예상했다시피, 상속 챕터에서 공부했던 강제 타입 변환, 즉 캐스팅(casting)에 대해서도 살펴볼 차례가 되었습니다. 인터페이스에서도 역시 구현 클래스가 자식 클래스의 포지션이 되기 때문에, 위에서 설명한 것처럼 자동 타입변환이 이루어진다고 했습니다. 즉, 인터페이스 타입으로 바뀐다는 것이죠.

 

그럼 상속 클래스때와 마찬가지로, 구현 클래스가 인터페이스 타입으로 자동변환이 이루어진 다음에는 구현 클래스에 있던 고유의 메서드는 사용할 수 없게 됩니다. 인터페이스에서 선언된 추상 메서드만 사용이 가능한 상태가 되지요. 예를 들어 인터페이스에 추상 메서드 3개가 선언되어 있고, 구현 클래스에는 이 추상 메서드 3개를 오버라이드 한 내용이 선언되어 있고 더불어 추가로 2개의 고유의 메서드가 더 있는 상황이라고 봅시다.

 

인터페이스 타입으로 자동 변환이 이루어진 후에는, 당연히 인터페이스 타입으로 변환되었기 때문에 추상 메서드 3개만 사용이 가능하게 됩니다. 이 때는 추가로 선언된 구현 클래스 고유 메서드 2개는 사용할 수 없습니다. 

 

하지만 만일 해당 변수를 통해서 이 메서드 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.
*/