Programing Language/Java

[Java] 인터페이스의 상속 및 다형화(Interface Inheritance & Polymorphism)

vinedpillar 2022. 7. 6. 00:47

인터페이스의 다중 구현

  • 먼저 인터페이스는 하위 클래스에서 여러 개의 인터페이스를 구현(implements)할 수 있습니다.

  • 일반적으로 인터페이스는 구체화되는 메서드가 없기 때문에 다중 구현을 해도 문제가 발생하지 않습니다.

  • 하지만, 인터페이스에 기본 메서드가 구현되어있고, 다중 구현을 통해 중복되는 상황이라면, 구현 클래스에서 반드시 이를 재정의 해주어야 합니다.
인터페이스 다중 구현 방법

// 다중 구현 인터페이스는 콤마(,)로 구분
public class 클래스이름 implements 인터페이스이름1, 인터페이스이름2, ... {
    
    구현되는 인터페이스 재정의 필요

}
인터페이스 다중 구현 예시

public interface Walkable {
    void startWalk();
    void stopWalk();
}


public interface Runnable {
    void startRun();
    viod stopRun();
}

// 여러 개의 인터페이스를 한 클래스에서 동시에 구현 
public class Human implements Walkable, Runnable {
    @Override
    // Walkable의 메서드 재정의
    
    @Override
    // Runnable의 메서드 재정의
}

 

 

 

 

인터페이스 간의 상속 및 다중 상속

  • 인터페이스도 상속이 가능하며, 클래스와 달리 다중 상속을 지원합니다.

  • 자식 인터페이스를 구현하는 클래스는 자식 인터페이스의 메서드 뿐 아니라 부모 인터페이스의 메서드도 재정의하여 사용해야 합니다.

  • 만약 자식 인터페이스 타입 변수로 구현 클래스의 인스턴스를 생성할 경우, 부모와 자식 인터페이스 모두의 매서드를 호출할 수 있습니다.

  • 부모 인터페이스 타입 변수로 구현 클래스의 인스턴스를 생성할 경우, 부모 인터페이스에 선언된 메서드만 호출 가능합니다. 
인터페이스 다중 상속 방법

// 다중 상속 인터페이스는 콤마(,)로 구분
public interface 자식인터페이스이름 extends 부모인터페이스이름1, 부모인터페이스이름2 ... {
	
	인터페이스 요소 작성

}
인터페이스 다중 상속 사용 예시

// 인터페이스A
public interface InterfaceA {
    void methodA():
}

// 인터페이스B
public interface InterfaceB {
    void methodB();
}

// 인터페이스A와 인터페이스B를 상속하는 인터페이스C
public interface InterfaceC extends InterfaceA, InterfaceB {
    void methodC();
}

// 인터페이스C의 구현 클래스
public class InterfaceCImple implements InterfaceC {
    // 인터페이스A의 methodA 구현
    public void methodA() {
    	System.out.println("인터페이스A 메서드 실행");
    }
    
    // 인터페이스B의 methodB 구현
	public void methodB() {
    	System.out.println("인터페이스B 메서드 실행");
    }
    
    // 인터페이스C의 methodc 구현
    public void methodC() {
    	System.out.println("인터페이스C 메서드 실행");
    }
}

// 테스트용 클래스
public class InterfaceExtendsExample {
    public static void main(String[] args) {
    	InterfaceCImpl iVar = new InterfaceCImpl();
        
        InterfaceA iA = iVar;
        iA.methodA();
        // 주석 처리된 메서드는 실행 불가
        // iA.methodB();
        
        InterfaceB iB = iVar;
        // 주석 처리된 메서드는 실행 불가
        // iB.methodA();
        iB.methodB();
    
    	InterfaceC iC = iVar;
        // 모든 메서드 사용 가능
        iC.methodA();
        iC.methodB();
        iC.methodC();
    }
}

 

 

 

 

인터페이스의 타입 변환

  • 인터페이스의 다형화는 구현과 상속, 구현된 클래스와 상속되는 인터페이스간의 타입 변환에 의해서 이루어집니다.

  • 인터페이스의 타입 변환은 인터페이스와 인터페이스를 구현한 클래스 사이에서 발생합니다.

  • 인터페이스 타입으로 선언된 변수에 구현 클래스의 인스턴스를 대입하면 해당 클래스의 인스턴스는 상위 인터페이스로 자동 타입 변환(promotion)이 됩니다.
    • 이 경우 인터페이스에 선언된 필드나 메서드만 사용할 수 있게 됩니다.

  • 반대로 인터페이스 타입으로 선언된 변수를 구현 클래스로 형변환 할 수도 있는데, 이 경우는 강제 형 변환(casting)이 필요합니다.
    (인터페이스보다 구현된 클래스의 자료 표현 범위가 더 넓기 때문)
    • 이 경우 형 변환한 구현 클래스의 모든 필드와 메서드를 사용할 수 있게 됩니다.

인터페이스 자동 형변환 예시

public interface InterfaceA {
    void methodA();
}

public class ClassA implements InterfaceA {
    void methodA() {
    	System.out.println("메서드A 실행");
    }
}

public class InterfacePromotionExample
    public static void main(String[] args) {
    	ClassA ca = new ClassA();
        InterfaceA ia;
        
        // 인터페이스 변수에 클래스 변수 대입 가능
        // 대입 시 자동으로 형변환 진행
        ia = ca;
    }
}
인터페이스 강제 형변환 예시

public interface InterfaceA {
    void methodA();
}

public class ClassA implements InterfaceA {
    void methodA() {
    	System.out.println("메서드A 실행");
    }
    
    void separateMethodA() {
    	System.out.println("클래스A의 단독 메서드");
    }
}

public class InterfacePromotionExample
    public static void main(String[] args) {
    	InterfaceA ia = new ClassA();
        
        // 인터페이스형 변수로는 클래스A에 따로 구현된 메서드는 사용 불가
        // ia.separateMethodA();
        
        // 구현된 클래스형으로 강제 형변환 후 클래스의 메서드 사용 가능
        ClassA ca = (ClassA) ia;
        ca.methodA();
        ca.separateMethodA();
    }
}

 

 

 

 

추상 클래스와 인터페이스의 차이

  • 추상 클래스는 공통된 특징을 가지는 여러 클래스의 특성을 모아 하나의 상위 객체로 만들어 놓은 것을 뜻합니다.

  • 인터페이스는 클래스 사이의 연결 부분으로 향후 연결된 객체가 변경될 가능성이 있을 때 유연하게 변경할 수 있도록 해줍니다.

  • 추상 클래스와 인터페이스는 모두 클래스의 추상화된 자료형으로 하위 클래스의 구현을 강제하기 위해서 사용됩니다.

  • 추상 클래스와 인터페이스의 가장 큰 차이는 다중 상속, 구현이 가능한가의 여부입니다.
    • 추상 클래스: 다중 상속이 불가능하며, 하나의 클래스는 하나의 추상 클래스만 상속이 가능합니다.
      ("클래스 A는 추상 클래스 B이다" 관계에서 사용)
    • 인터페이스: 다중 구현을 지원하며, 인터페이스간의 다중 상속도 지원합니다.
      ("클래스 A는 인터페이스 B의 기능을 가지고 있다" 관계에서 사용)