ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java 자바] 8. 인터페이스 ② 사용 방법, 인터페이스 상속, 디폴트 메소드
    Programming/Java 2022. 8. 9. 20:50
    반응형

    8-4. 인터페이스 사용

    인터페이스로 구현 객체를 사용하려면 인터페이스 변수를 선언하고 구현 객체를 대입해야 함

    8-4-1. 추상 메소드 사용

    구현 객체가 인터페이스 타입에 대입되면 인터페이스에 선언된 추상 메소드를 개발 코드에서 호출할 수 있음.
    이 때, 메소드는 구현 객체에서 선언된 메소드가 자동으로 실행됨.

    public class RemoteControlTest {
    	public static void main(String[] args) {
        
    		RemoteControl rc = new Television();
    		rc.turnOn();	// TV가 켜집니다.
    	}
    }

    8-4-2. 디폴트 메소드 사용

    - 디폴트 메소드는 인터페이스에 선언되지만, 인터페이스를 통해 바로 사용은 불가능함
    - 보통 인터페이스의 모든 구현 객체가 가지고 있는 기본 메소드로 사용되나, 구현 클래스에서 오버라이딩하여 사용도 가능함

    // 아래와 같이 인터페이스명으로 바로 접근 불가능
    RemoteControl.디폴트메소드명();
    
    // 구현객체를 통해서만 호출 가능
    RemoteControl rc = new Television();
    rc.디폴트메소드명();

    8-4-3. 정적 메소드 사용

    - 인터페이스로 바로 호출 가능

    RemoteControl.정적메소드명();

    8-5. 타입 변환과 다형성

    메소드에서 매개 변수를 인터페이스 타입으로 선언할 경우, 메소드 호출시 매개값으로 여러 가지 종류의 구현 객체를 줄 수 있음

    8-5-1. 자동 타입 변환 (Promotion)

    - 구현 객체가 인터페이스 타입으로 변환되는 것
    - 인터페이스 구현 클래스를 상속하여 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환 가능

    8-5-2. 필드의 다형성

    - 필드 타입으로 인터페이스를 선언하면 필드값으로 다양한 인터페이스의 구현 객체들을 대입할 수 있음

    //Tire interface를 구현한 HankookTire, KumhoTire 객체가 있다고 할 때.
    
    //Car.java
    public class Car {
      Tire frontLeftTire = new HankookTire();
      Tire frontRightTire = new HankookTire();
    }
    
    //CarTest.java
    public class CarTest {
      public static void main(String[] args) {
        Car myCar = new Car();
        myCar.frontLeftTire = new KumhoTire();
      }
    }

    8-5-3. 인터페이스 배열로 구현 객체 관리

    인터페이스 배열을 통한 관리도 가능

    Tire[] tires = {
      new HankookTire();
      new HankookTire();
    }
    
    tires[1] = new KumhoTire();

    8-5-4. 매개 변수의 다형성

    메소드 호출시 매개변수에 인터페이스 타입으로 선언하고 호출할 때는 구현 객체를 대입하는 것도 가능 

    //Driver.java
    public class Driver {
      public void drive(Vehicle vehicle) {
        vehicle.run();
      }
    }
    
    //Vehicle.java
    public interface Vehicle {
      public void run();
    }
    
    //Bus.java
    public class Bus implements Vehicle {
      @Override
      public void run() {
        System.out.println("버스가 달립니다.");
      }
    }
    
    //Taxi.java
    public class Taxi implements Vehicle {
      @Override
      public void run() {
        System.out.println("택시가 달립니다.");
      }
    }
    
    //DriverTest.java
    public class DriverTest {
      public static void main(Strings[] args) {
        Driver drvier = new Driver();
        
        Bus bus = new Bus();
        Taxi taxi = new Taxi();
        
        driver.drive(bus);
        driver.drive(taxi);
      }
    }

    8-5-5. 강제 타입 변환 (Casting)

    구현객체가 인터페이스 타입으로 자동변환될 경우, 구현객체 고유의 필드/메소드는 사용이 불가능함
    - 이 경우, 강제 타입 변환을 해서 구현 클래스 타입으로 변환한 후 구현 클래스의 필드와 메소드를 사용할 수 있음

    Vehicle vehicle = new Bus();
    vehicle.bus고유메소드명();		// 사용불가
    
    Bus bus = (Bus) vehicle;
    bus.bus고유메소드명();		// 사용가능

    8-5-6. 객체 타입 확인 (instanceof)

    강제 타입 변환을 하기 전에는 매개값이 어떤 객체인지 Instanceof 연산자로 확인 후 안전하게 변환해야 함

    8-6. 인터페이스 상속

    인터페이스끼리 다른 인터페이스를 상속할 수 있으며, 다중 상속 역시 가능함
    - 이 때, 이 하위인터페이스를 구현하는 클래스는 하위, 상위 인터페이스의 모든 추상 메소드에 대한 실체 메소드를 가지고 있어야 함

    public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2 {...}

    8-7. 디폴트 메소드와 인터페이스 확장

    8-7-1. 디폴트 메소드의 필요성

    - 기존 인터페이스를 확장해 새로운 기능을 추가하기 위해 필요
    - 기존 인터페이스에 새로운 메소드를 추가할 경우, 이 인터페이스를 사용하고 있던 클래스는 해당 메소드가 없기 때문에 컴파일 에러 발생
    - 추가한 메소드를 default 타입으로 선언할 경우, 기존 클래스에서는 오류 없이 사용 가능
    - 신규로 해당 인터페이스를 사용하는 클래스들은 default메소드를 그대로 혹은 수정하여 사용 가능

    8-7-2. 디폴트 메소드가 있는 인터페이스 상속

    - 디폴트 메소드의 경우, 상속시에 그대로 사용하거나 오버라이딩할 수 있음
    - 자식인터페이스에서 구현된 객체 역시도 부모인터페이스의 디폴트 메소드에 바로 접근 가능

    반응형

    댓글

Designed by Tistory.