본문 바로가기

프로그래밍언어/Java

[Java 기본] 인터페이스

인터페이스


인터페이스는 class 가 아닌 interface 키워드를 사용한다. public abstract 키워드는 생략 가능하다. 

  • 인터페이스의 메서드는 모두 public, abstract 이다. 
  • 메서드에 public abstact를 생략할 수 있다. 
  • 다중 상속을 지원한다. 

 

인터페이스와 멤버 변수


인터페이스에서 멤버 변수는 public, static, final 이 모두 포함되었다고 간주된다. 

인터페이스를 통해서 상수에 접근할 수 있다고 보면된다.  

 

 

예제


InterfaceAnimal.java

package poly.ex4;

public interface interfaceAnimal {
    void sound(); //public abstact
    void move();
}

 

Cat.java

public class Cat implements interfaceAnimal{
    @Override
    public void sound() {
        System.out.println("냐옹");
    }

    @Override
    public void move() {
        System.out.println("냥이 이동");
    }
}

 

Dog.java

public class Dog implements interfaceAnimal {

    @Override
    public void sound() {
        System.out.println("멍멍");
    }

    @Override
    public void move() {
        System.out.println("댕댕이 이동");
    }
}

 

Caw.java

public class Caw implements interfaceAnimal{
    @Override
    public void sound() {
        System.out.println("음메");
    }

    @Override
    public void move() {
        System.out.println("집으로 이동");
    }
}

 

 

InterfaceMain.java

public class InterfaceMain {

    public static void main(String[] args) {
        Dog dog = new Dog();
        Caw caw = new Caw();
        Cat cat = new Cat();

        soundAnimal(dog);
        soundAnimal(cat);
        soundAnimal(caw);

    }

    public static void soundAnimal(interfaceAnimal animal) {
        System.out.println("동물 소리 테스트 시작");
        animal.sound();
        System.out.println("동물 소리 테스트 종료");
    }

}

 

실행결과

 

 

인터페이스를 사용하는 이유


모든 메서드가 추상 메서드인 경우 추상 클래스를 만들어도 되고, 인터페이스를 만들어도 된다. 그런데 왜 인터페이스를 사용해야 할까?

  • 제약: 인터페이스를 만드는 이유는 인터페이스를 구현하는 곳에서 인터페이스의 메서드를 반드시 구현하라는 제약을 주기 위해서이다.  추상클래스의 경우 누군가 실행 가능한 메서드를 끼워 넣을 수도 있다. 이 경우 추가된 기능을 자식 클래스에서 구현하지 않을 수도 있다. 인터페이스를 만들면 이 문제를 원천 차단할 수 있다.  
  • 다중 구현 : 자바에서 클래스 상속은 부모를 하나만 지정할 수 있다. 반면에 인터페이스는 부모를 여러명 두는 다중 구현이 가능하다. 

 

인터페이스 다중구현


자바는 클래스의 다중 상속을 지원하지 않는다. 만약 AirplandCar가 Airplane과 Car를 상속받는다고 가정해보자. AirplaneCar에서 move() 메서드를 호출할 때 어떤 부모의 move()를 호출할 지 애매한 문제가 발생한다. 이를 다이아몬드 문제라고 한다. 또한 다중 상속을 사용하면 클래스 계층 구조가 매우 복잡해질 수 있다. 이런 문제점 때문에 자바는 클래스의 다중 상속을 허용하지 않는다. 대신 인터페이스의 다중 구현을 허용하여 이러한 문제를 피한다. 

 

예제


InterfaceA.java

package poly.diamond;

public interface InterfaceA {
    void methodA();
    void methodCommon();
}

 

InterfaceB.java

package poly.diamond;

public interface InterfaceB {
    void methodB();
    void methodCommon();
}

 

Child.java

package poly.diamond;

public class Child implements InterfaceA, InterfaceB{

    @Override
    public void methodA() {
        System.out.println("Child methodA");
    }

    @Override
    public void methodB() {
        System.out.println("Child methodB");
    }

    @Override
    public void methodCommon() {
        System.out.println("Child methodCommon");
    }

}

 

 

DiamondMain.java

package poly.diamond;

public class DiamondMain {

     public static void main(String[] args) {
        InterfaceA a = new Child();
        a.methodA();
        a.methodCommon();

        InterfaceB b = new Child();
        b.methodB();
        b.methodCommon();
    }
}

 

실행결과

 

=>

1. a.methodCommon()을 호출하면 먼저 x001 Child 인스턴스를 찾는다.

2. 변수 a가 InterfaceA 타입이므로 해당 타입에서 methodCommon()을 찾는다.

3. methodCommon()은 하위 타입인 Child에서 오버라이딩 되어 있다. 따라서 Child의 methodCommon()이 호출된다. 

 

 

 

 

* 인프런 '김영한의 실전 자바 - 기본편'을 참고하여 작성하였습니다.