티스토리 뷰

주의 사항!

  • 이 글은 제가 직접 공부하는 중에 작성되고 있습니다.
  • 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
  • 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.


앞서 상속에서 타입 변환과 다형성에 대해 살펴보았습니다. 인터페이스도 다형성을 구현하는 기술이 사용됩니다. 오히려 요즘은 상속보다는 인터페이스를 통해서 다형성을 구현하는 경우가 더 많습니다. 상속에서 부모 타입에 어떤 자식 객체를 대입하느냐에 따라 실행결과가 달라지듯이, 인터페이스 타입에 어떤 구현 객체를 대입하느냐에 따라 실행 결과가 달라집니다. 상속은 같은 종류의 하위 클래스를 만드는 기술이고, 인터페이스는 사용 방법이 동일한 클래스를 만드는 기술이라는 개념적 차이는 있지만 둘 다 다형성을 구현하는 기술임에는 틀림없습니다. 

 

(그럼 Tire와 HankookTire, KumhoTire의 관계는 상속과 인터페이스 중 어떤 것이 더 어울릴까요? HankookTire와 KumhoTire 둘 다 자동차에 장착되는 정해진 규격을 가지는 타이어라는 관점에서 상속의 관계로 두는 것이 좋을까요? 아니면 HankookTire와 KumhoTire 둘 다 정해진 규격을 가져야만 자동차에 장착될 수 있고, 자동차가 달리면 회전하고, 멈추기도 하고, 내구도가 감소하기도 하고, 터지기도 하는 타이어의 공통된 기능(?) 면에서 인터페이스 관계로 두는 것이 좋을까요?

 

상속이나 인터페이스나 어느 것을 이용해도 상관은 없겠지만 제 개인적인 생각으로는 인터페이스가 상속보다는 사용성이 더 좋고, 클래스와 인터페이스는 구분이 확실해서 더 선호되는 게 아닐까 생각됩니다. 상속의 관계에서는 부모와 자식 모두 클래스와 클래스이기 때문에 유지, 보수할 때에 부모와 자식을 구분하는 일이 조금은 더 번거롭지 않을까 생각됩니다.)

 

프로그램을 개발할 때 인터페이스를 사용해서 메서드를 호출하도록 코딩을 했다면, 구현 객체를 교체하는 것은 매우 손쉽고 빠르게 할 수 있습니다. 프로그램 소스 코드는 변함이 없는데, 구현 객체를 교체함으로써 프로그램의 실행 결과가 다양해집니다. 이것이 인터페이스의 다형성입니다.

 

인터페이스의 타입 변환과 다형성은 상속에서의 것과 매우 매우 닮아 있습니다. 그냥 똑같다고 봐도 될 것 같습니다. 상속과 관련해서 타입 변환과 다형성은 앞서 설명했기 때문에 인터페이스 타입 변환과 다형성에 대한 설명은 간단하게만 하겠습니다. 만약 끝까지 다 읽고도 잘 이해하 가지 않는다면 아래의 링크를 통해 상속의 타입 변환과 다형성에 대한 글을 보시길 권합니다.

2021.04.08 - [JAVA 공부일지] - 자바, 객체 타입 변환과 다형성

 

자바, 객체 타입 변환과 다형성

주의 사항! 이 글은 제가 직접 공부하는 중에 작성되고 있습니다. 따라서 제가 이해하는 그대로의 내용이 포함됩니다. 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다. 다형성은 같은

koey.tistory.com

 

자동 타입 변환

구현 객체가 인터페이스 타입으로 변환되는 것은 자동 타입 변환에 해당합니다. 인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환시킬 수 있습니다. 

 

필드의 다형성

자동차를 설계할 때 다음과 같이 필드 타입으로 인터페이스를 선언하게 되면 필드 값으로 한국 타이어 또는 금호 타이어 객체를 대입할 수 있습니다.

public class Car
{
	Tire frontLeftTire = new HankookTire();
	Tire frontRightTire = new HankookTire();
	Tire rearLeftTire = new HankookTire();
	Tire rearRightTire = new HankookTire();
}

Car 객체를 생성한 후, 초기값으로 대입한 구현 객체 대신 다른 구현 객체를 대입할 수도 있습니다. 이것이 타이어 교체에 해당합니다.

Car myCar = new Car();
myCar.frontLeftTire  = new KumhoTire();
myCar.frontRightTire  = new KumhoTire();

 

인터페이스 배열로 구현 객체 관리

Car 클래스에서 4개의 타이어 필드를 다음과 같이 인터페이스 배열로 관리할 수도 있습니다.

Tire[] tires = {
	new HankookTire(),
	new HankookTire(),
	new HankookTire(),
	new HankookTire(),
}

배열로 관리하면 인덱스만으로 4개의 바퀴를 모두 표현할 수 있으므로 대입이나 제어문에서 활용하기가 매우 쉽습니다.

 

매개 변수의 다형성

자동 타입 변환은 필드의 값을 대입할 때에도 발생하지만, 주로 메서드를 호출할 때 많이 발생합니다. 이번에는 매개 변수를 인터페이스 타입으로 선언하고 호출할 때에는 구현 객체를 대입합니다. 예를 들어 다음과 같이 Driver 클래스에서는 drive() 메서드가 정의되어 있는데 Vehicle 타입의 매개 변수가 선언되어 있습니다.

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

만약 Bus나 Taxi와 같은 클래스가 Vehicle의 구현 클래스로 정의되어 있다면 drive() 메서드에 어떤 구현 객체가 들어가느냐에 따라 메서드 실행 결과는 다르게 할 수 있습니다.

 

강제 타입 변환

구현 객체가 인터페이스 타입으로 자동 변환하면, 인터페이스에 선언된 메서드만 사용 가능하다는 제약 사항이 따릅니다. 예를 들어 인터페이스에는 세 개의 메서드가 선언되어 있고, 클래스에는 다섯 개의 메서드가 선언되어 있다면, 인터페이스로 호출 가능한 메서드는 세 개뿐입니다.

 

하지만 경우에 따라서는 구현 클래스에 선언된 필드와 메서드를 사용해야 할 경우도 발생합니다. 이때 강제 타입 변환을 해서 다시 구현 클래스 타입으로 변환한 다음, 구현 클래스의 필드와 메서드를 사용할 수 있습니다. 물론 인터페이스 타입에 대입되어 있는 구현 객체의 타입으로만 강제 타입 변환이 가능합니다. 만약 인터페이스 타입 Vehicle에 Bus가 구현 객체로 대입되어 있는데, 이를 Bus 타입으로 강제 변환하는 것은 가능해도 Taxi 타입으로 강제 변환하는 것은 불가능합니다.

 

객체 타입 확인

상속에서는 어떤 자식 클래스가 부모 클래스 타입으로 변환되었는지 확인하기 위해 instanceof 연산자를 사용했습니다. 이 연산자는 인터페이스에서도 동일하게 사용할 수 있습니다. 예를 들어 Vehicle 인터페이스 타입으로 변환된 객체가 Bus인지 확인하려면 다음과 같이 작성하면 됩니다.

if(vehicle instanceof Bus)
{
	Bus bus = (Bus)vehicle;
}

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함