[Java] 인터페이스(Interface)

JUNBEOM PARK·2022년 2월 17일
0

🧨 Java

목록 보기
24/33
post-thumbnail

🤔 인터페이스(Interface) ?

Java에서는 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러 가지 문제가 발생할 수 있어 클래스를 통한 다중 상속은 지원하지 않는다.

하지만 다중 상속의 이점을 버릴 수 없어Java에서는 인터페이스(Interface)라는 것을 통해 다중 상속을 지원하고 있다.

인터페이스(Interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미한다.

추상클래스(Abstract Class)는 추상 메소드 뿐만 아니라 생성자, 필드, 일반 메소드도 포함 할 수 있지만
인터페이스(Interface)는 오로지 추상 메소드와 상수만을 포함한다.



1. 인터페이스(Interface) 선언

[public] interface 인터페이스이름 { ... }

public interface Predator { .... }

interface의 접근 제어자는 public만 가능하다. interface는 class 설계도 이기 때문에 존재 목적이 애초에 공개이기 때문이다.

interface는 객체로 생성할 수 없기 때문에, 생성자를 가질 수 없다.

2. 인터페이스(Interface) 구현

class Tiger extends Animal implements Predator{ ... }

class Lion extends Animal implements Predator{ ... }

위와 같이 implements 키워드를 사용한다.

3. 인터페이스(Inerface) 상속

인터페이스도 다른 인터페이스를 상속 할 수 있다.
클래스는 다중 상속을 허용하지 않지만, 인터페이스는 다중 상속을 허용한다.

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

하위 인터페이스를 구현하는 구현 클래스에서는 하위 인터페이스의 추상 메소드상속하는 모든 상위 인터페이스의 추상메소드의 실체 메소드로 구현해야 한다.

하위인터페이스 변수 = new 구현클래스();
상위인터페이스1 변수 = new 구현클래스();
상위인터페이스2 변수 = new 구현클래스();

하위 인터페이스 변수는 하위인터페이스, 상위 인터페이스1, 상위 인터페이스2의 실체 메소드를 모두 사용할 수 있다.
상위 인터페이스1 변수는 상위 인터페이스1의 실체 메소드를 사용할 수 있다.
상위 인터페이스2 변수는 상위 인터페이스2의 실체 메소드를 사용할 수 있다.



4. 인터페이스(Interface) 메소드

기본 메소드(Default Method)

  • default 메소드를 이용하면 인터페이스 내부에서 코드가 존재할 수 있다.
  • default 메소드는 오버라이딩이 강제적이 아닌 선택적이라서 오버라이딩을 하지 않을시 기본 구현된 코드가 실행된다.
  • default 키워드는 무조건 명시해야 한다.
  • 하위호환성을 위해 주로 사용한다.
public interface Phone {
    int version = 12;

    String getManufacturer();
    String getOS();

    default void printRing(){
        System.out.println("Sound : Ring Ring~~");
    }
}
public class Galaxy implements Phone{
    @Override
    public String getManufacturer() {
        return "Samsung";
    }

    @Override
    public String getOS() {
        return "Android";
    }

    @Override
    public void printRing() {
        System.out.println("Sound : Ring~~~~~~~");
    }
}

static 메소드

  • static 메소드는 인스턴스 생성 없이 인터페이스 이름을 통해서 직접 메소드 호출이 가능하다.
  • 인터페이스를 구현하는 클래스에서 재정의가 불가능하다.
public interface Phone {
    int version = 12;

    String getManufacturer();
    String getOS();

    default void printRing(){
        System.out.println("Sound : Ring Ring~~");
    }

    static void printUser(String user){
        System.out.println("User : "+user);
    }
}
public class Main {
    public static void main(String[] args) {
        Phone galaxy= new Galaxy();
        Phone iphone = new IPhone();

        System.out.println(galaxy.getManufacturer());
        System.out.println(galaxy.getOS());
        galaxy.printRing();


        System.out.println();
        System.out.println(iphone.getManufacturer());
        System.out.println(iphone.getOS());
        iphone.printRing();

        // static 메소드 사용
        Phone.printUser("Hong Gil Dong");
    }
}

private 메소드

  • 코드 구현시 복잡한 코드를 한 번에 구현하는 것 보다 작은 메소드를 작성하여 복잡한 메소드를 구현하는 것이 재사용, 유지보수 측면에서 효율적이다.
  • private 메소드를 이용하여 작은 메소드를 구현하되 외부에서 볼 수 없고 사용할 수 없도록 할게 만드는 메소드이다.

public interface Phone {
    int version = 12;

    String getManufacturer();
    String getOS();

    default void printRing(){
        // private 메소드 사용
        printInfo();
        System.out.println("Sound : Ring Ring~~");
    }

    static void printUser(String user){
        // static private 메소드 사용
        getUser(user);
    }

    private void printInfo(){
        System.out.println("Print Information");
    }

    private static void getUser(String user){
        System.out.println("User : "+user);
    }
}
public class Main {
    public static void main(String[] args) {
        Phone galaxy= new Galaxy();
        Phone iphone = new IPhone();

        System.out.println(galaxy.getManufacturer());
        System.out.println(galaxy.getOS());
        galaxy.printRing();


        System.out.println();
        System.out.println(iphone.getManufacturer());
        System.out.println(iphone.getOS());
        iphone.printRing();

        Phone.printUser("Hong Gil Dong");
    }
}

5. 추상클래스와 인터페이스 비교

  • 인터페이스는 특정 기능을 구현하기 위한 필수 규격을 주는 것으로 추상클래스는 미완성 설계도, 인터페이스는 기본 설계도로 보면 된다.
  • 모든 클래스를 인터페이스를 사용한다면 공통된 기능을 모두 구현해야 하기 때문에 번거롭다. 이럴 경우 추상클래스를 이용해야 한다.
  • 추상클래스만 사용하기에는 다중상속이 불가능 하기 때문에 각각 다른 추상클래스를 구현하는데 공통된 기능이 존재할 경우는 인터페이스가 필요하다.

참고자료
https://limkydev.tistory.com/197
http://www.tcpschool.com/java/java_polymorphism_interface
https://wikidocs.net/217
https://interconnection.tistory.com/129
https://math-coding.tistory.com/169

profile
DB 엔지니어👍

0개의 댓글