Java - 인터페이스#2

이새봄·2022년 9월 4일

Java

목록 보기
6/11

이 글은 이것이 자바다를 참고하여 작성되었습니다.

타입 변환과 다형성

자동 타입 변환(Promotion)

인터페이스 변수 = 구현객체;

  • 인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환할 수 있다.

필드의 다형성

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

다음과 같이 필드 타입으로 타이어 인터페이스를 선언하게 되면 필드값으로 한국 타이어 또는 금호 타이어 객체를 대입할 수 있다. 자동 타입 변환이 일어난다.

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

Car 객체를 생성한 후 초기값으로 대입한 구현 객체 대신 다른 구현 객체를 대입할 수도 있다.

매개변수의 다형성

  • 매개변수를 인터페이스 타입으로 선언하고 호출할 때는 구현 객체를 대입한다.
class Driver {
    public drive(Vehicle vehicle) {
        vehicle.run();
    }
}   
public interface Vehicle {
        public void run();
}   

Vehicle을 다음과 같이 인터페이스 타입이라고 가정.
Bus가 구현 클래스라면 Driver의 drive() 메소드를 호출할 때 Bus 객체를 생성해서 매개값으로 줄 수 있다.

Driver driver = new Driver();
Bus bus = new Bus();
driver.drive(bus);

자동 타입 변환 발생 Vehicle vehicle = bus;
→ 매개 변수의 타입이 인터페이스일 경우 어떤 구현 객체도 매개값으로 사용할 수 있다.
→ 매개값으로 어떤 구현 객체가 제공되느냐에 따라 메소드의 실행 결과는 다양해질 수 있다. (매개변수의 다형성)

강제 타입 변환(Casting)

구현 객체가 인터페이스 타입으로 자동 변환하면 인터페이스에 선언된 메소드만 사용 가능하다는 제약 사항이 따른다.
→ 구현 클래스에 선언된 필드와 메소드를 사용하기 위해서 강제 타입 변환 후 다시 구현 클래스 타입으로 변환한 다음 구현 클래스의 필드와 메소드를 사용할 수 있다.
구현클래스 변수 = (구현클래스) 인터페이스변수;

  • 구현 객체가 인터페이스 타입으로 변환되어 있는 상태에서만 가능하다.

객체 타입 확인(instanceof)

  • 어떤 구현 객체가 인터페이스 타입으로 변환되었는지 확인하려면 instanceof 연산자를 사용할 수 있다.
if(vehicle instanceof Bus){
    Bus bus = (Bus) vehicle;
}
  • 좌항 : 인터페이스, 우항 : 구현객체
  • 안전하게 강제 타입 변환을 할 수 있다.

인터페이스 상속

  • 클래스와 달리 다중 상속을 허용한다.
public interface 하위인터페이스 
extends 상위인터페이스1, 상위인터페이스2 {...}

하위 인터페이스를 구현하는 클래스는 하위 인터페이스의 메소드뿐만 아니라 상위 인터페이스의 모든 추상 메소드에 대한 실체 메소드를 가지고 있어야 한다.
→ 구현 클래스로부터 객체를 생성하고 나서 다음과 같이 하위 및 상위 인터페이스 타입으로 변환이 가능하다.

하위인터페이스 변수 = new 구현클래스(...);
상위인터페이스1 변수 = new 구현클래스(...);
상위인터페이스2 변수 = new 구현클래스(...);
  • 하위 인터페이스로 타입 변환이 되면 상/하위 인터페이스에 선언된 모든 메소드를 사용할 수 있다.
  • 상위 인터페이스로 타입 변환되면 상위 인터페이스에 선언된 메소드만 사용 가능하다.

디폴트 메소드와 인터페이스 확장

디폴트 메소드는 인터페이스에 선언된 인스턴스 메소드이다.
→ 구현 객체가 있어야 사용할 수 있다.
선언은 인터페이스에서 하고 사용은 구현 객체를 통해 한다.

디폴트 메소드의 필요성
: 기존 인터페이스를 확장해서 새로운 기능을 추가하기 위해서.

  • 추상 메소드가 아니기 때문에 구현 클래스에서 실체 메소드를 작성할 필요가 없다.

디폴트 메소드가 있는 인터페이스 상속

  • 부모 인터페이스에 디폴트 메소드가 정의되어 있을 경우 자식 인터페이스에서 디폴트 메소드를 활용하는 방법
    • 디폴트 메소드를 단순히 상속만 받는다.
    • 디폴트 메소드를 재정의(Override)해서 실행 내용을 변경한다.
    • 디폴트 메소드를 추상 메소드로 재선언한다.

0개의 댓글