본문 바로가기
개발 관련 지식/JAVA

인터페이스 타입변환과 다형성

by 권태일1147 2020. 4. 2.

상속은 같은 종류의 하위 클래스를 만드는 기술이고, 인터페이스는 사용 방법이 동일한 클래스를 만드는 기술이다.

 

메소드 호출 시 어떤 구현 객체를 매개값으로 주느냐에 따라서 메소드의 실행 결과는 다르게 나온다.

 

예를 들면, 인터페이스 A의 구현 클래스 B와 C가 있을 때, B클래스를 통해서 원하는 결과가 나오지 않으면 간단하게 C클래스로 바꿔서 실행 할 수 있다.

그것을 유용하게 바꾸기 위해 인터페이스는 메소드의 매개 변수로 많이 사용된다. 매개 변수를 인터페이스 타입으로 선언하면 메소드 호출 시 매개 값으로 다양한 구현 객체를 주어서 다양한 실행 결과가 나오게 할 수 있다.

 

public interface A {
    // ....
}

public class B implements A {
    // ....
}

public class C implements A {
    // ....
}

public class Main {
    public void methodD(A a){
        // ....
    }
}

매개 변수 a의 값으로 B 객체 또는 C 객체를 줄 수 있다. 이 때 B 객체 또는 C 객체를 넣으면 객체가 자동 타입 변환이 일어난다. 

 

 

 

필드의 다형성

HankookTire와 KumhoTire 에서 공통적인 Tire 부분을 추출해서 인터페이스로 만들어서 필드에 다형성을 적용해볼 수 있다.

// 인터페이스 Tire.java

pulbic interface Tire {
    public void roll(); // 추상 메소드, 반드시 오버라이딩 해야한다.
}

 

// 구현 클래스 HankookTire.java

public class HankookTire implements Tire {
    @Override
    public void roll() {
        System.out.println("한국타이어가 굴러갑니다.");
    }
}

 

// 구현 클래스 KumhoTire.java

public class KumhoTire implements Tire {
    @Override
    public void roll() {
        System.out.println("금호타이어가 굴러갑니다.");
    }
}

 

// 구현 객체를 적용하는 Car.java

public class Car {
    Tire frontLeftTire = new HankookTire();
    Tire frontRightTire = new HankookTire();
    Tire backLeftTire = new HankookTire();
    Tire backRightTire = new HankookTire();
    
    public void run() {
        frontLeftTire.roll();
        frontRightTire.roll();
        backLeftTire.roll();
        backRightTire.roll();
    }
}

 

// 실행 클래스 Main.java
public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        
        car.run();
        
        car.frontLeftTire = new KumhoTire();
        car.frontRightTire = new KumhoTire();
        
        car.run();
    }
}

Car 객체의 필드를 다양하게 해서 run() 메소드를 실행하면 roll() 의 결과가 다르게 나타난다. 

 

 

매개 변수의 다형성

상속과 비슷하게 매개변수에 인터페이스 타입을 선언하고 호출 할 때는 구현 타입으로 호출하는 방법이다.

// 인터페이스를 적용하는 Driver.java

public class Driver {
    public void drive(Vehicle vehicle) {  // 인터페이스 타입을 매개변수로 선언해서 구현 객체를 받을 수 있도록 한다.
        vehicle.run(); // 받은 구현 객체의 run() 메소드를 실행한다.
    }   // 인터페이스의 run() 추상 메소드를 구현 클래스에서 구현해야 한다.
}

 

// 인터페이스 Vehicle.java

public interface Vehicle {
    public void run(); // 추상 메소드
}

 

// 구현 클래스 Bus.java

public class Bus {
    @Override
    public void drive() {
        System.out.println("버스가 달립니다");
    }
}

 

// 구현 클래스 Taxi.java

public class Taxi {
    @Override
    public void drive() {
        System.out.println("택시가 달립니다");
    }
}

 

// 실행하는 Main.java

public class Main {
    public static void main(String[] args) {
        Driver driver = new Driver();
        
        Bus bus = new Bus();
        Taxi taxi = new Taxi();
        
        driver.drive(bus);   // 다양한 구현 객체를 매개변수에 넣어서 구현 클래스의 구현된 메소드를 실행한다.
        driver.drive(taxi);
    }
}

매개변수를 다양하게 함으로써 실행결과를 다르게 할 수 있다.

 

 

강제 타입 변환

참조 객체가 인터페이스 타입으로 자동 타입 변환이 되면 인터페이스에 있는 메소드만 사용할 수 있게 된다. 근데 경우에 따라서 바뀐 타입을 다시 클래스 타입으로 바꿔서 클래스에 있는 필드와 메소드를 사용해야 할 때가 있다. 이 때 강제 타입 변환을 사용하는 것이다.

// 인터페이스 Vehicle.java

public class Vehicle {
    public void run();
}


// 구현 클래스 Bus.java

public class Bus implements Vehicle {
   @Override
   public void run() {
       System.out.println("버스가 달립니다.");
   }
   
   public void checkFare() {
       System.out.prinlnt("승차 요금 체크");
   }
}


// 실행 클래스 Main.java
public class Main {
    public static void main(String[] args) {
        Vehicle vehicle = new Bus();  // 자동 타입 변환으로 인해 인터페이스 메소드밖에 사용 불가.
        
        vehicle.run();
        
        Bus bus = (Bus) vehicle; // 강제 타입 변화
        bus.run();
        bus.checkFave;  // 구현 객체의 메소드 사용 가능.
    }
}

'개발 관련 지식 > JAVA' 카테고리의 다른 글

인터페이스에서 디폴트 메소드  (0) 2020.04.02
인터페이스 상속  (0) 2020.04.02
인터페이스  (0) 2020.04.01
추상 클래스  (0) 2020.04.01
다형성  (0) 2020.03.31