본문 바로가기

프로그래밍/Java

인터페이스

인터페이스란?

자바에서는 클래스를 통한 다중 상속은 지원하지 않지만 인터페이스를 통해 다중 상속을 지원한다.
인터페이스는 일종의 추상클래스로 추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화의 정도가 더 높아 추상메서드와 상수만을 가질 수 있다.

인터페이스를 정의하는 방법

  1. 클래스의 작성하는 방법과 같으며 class대신 interface를 사용한다.
  2. 클래스와 달리 모든 멤버는 public static final이어야 한다.
  3. 모든 메서드는 public abstract이어야 하며 생략 가능하다.
    • 단 static메서드와 default메서드는 예외이다(JDK 1.8부터)
interface 인터페이스이름 {
    public static final 타입 상수이름 = 값;
    public abstract 메서드이름(매개변수);
}

인터페이스를 구현하는 방법

인터페이스도 추상클래스 처럼 자신이 직접 인스턴스를 생성할 수 없으며 구현해줄 클래스를 만들어야 한다. 이때 추상메서드와는 다르게 implements 키워드를 사용하며 모든 추상메서드를 구현하지 않으면 abstact를 붙여 추상클래스로 선언해야 한다.

class 클래스명 implements 인터페이스명{}
public interface Car {
    public abstract void printFuel();
    public abstract String getFuel();
}

public class ElectricCar implements Car {
    @Override
    public void printFuel() {
        System.out.println("이 차의 연료는 전기");
    }

    @Override
    public String getFuel() {
        return "전기";
    }
}

public abstract class GasCar implements Car{
    @Override
    public void printFuel() {
        System.out.println("이 차의 연료는 가스");
    }

}

인터페이스를 레퍼런스를 통해 구현체를 사용하는 방법

자식 클래스의 인스턴스를 부모 클래스의 타입의 참조변수로 참조하는 것이 가능하였는데(다형성) 인터페이스 또한 가능하다.

public class CarManager {
    public static Car getCar(String fuel) {
        if (fuel.equals("기름"))
            return new OilCar();
        else if (fuel.equals("전기"))
            return new ElectricCar();
        else
            return new OtherCar();
    }
}
Car car1 = CarManager.getCar("전기");   // Car car1 = new ElectricCar();
Car car2 = CarManager.getCar("기름");
Car car3 = CarManager.getCar("고급 휘발유");
car1.printFuel();
car2.printFuel();
car3.printFuel();

출력 결과

이 차의 연료는 전기
이 차의 연료는 기름
이 차의 연료는 분류되지 않음

인터페이스 상속

인터페이스는 다른 인터페이스로부터만 상속할 수 있으며 클래스와 다르게 여러 인터페이스를 상속할 수 있다.
클래스의 상속과 마찬가지로 자식은 부모에 정의된 모든 멤버를 상속받는다.

public class ElectricCar implements Car, Vehicle {
    @Override
    public void printFuel() {
        System.out.println("이 차의 연료는 전기");
    }

    @Override
    public String getFuel() {
        return "전기";
    }
}

인터페이스의 기본 메소드

Java8부터 기본 구현을 제공하는 메소드로 디폴트 메소드는 추상 메소드가 아니므로 추가되어도 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
메소드 앞에 default키워드를 붙이고 추상메서드와 다르게 몸통{}이 있어야 한다.
접근제어자는 public이며 생략 가능하다.

public interface Car {
    public abstract void printFuel();
    public abstract String getFuel();
    default void newMethod(){}
}

새로 추가한 메소드가 기존의 메소드와 이름이 같아 충돌하는 경우가 발생할 수 있다.

  1. 여러 인터페이스의 기본 메소드간 충돌
    • 인터페이스를 구현한 클래스에서 기본 메소드를 오버라이딩
  2. 기본 메서드와 부모클래스의 메소드간 충돌
    • 부모 클래스의 메소드가 상속되고 기본 메소드 무시

인터페이스의 static 메소드

static 메소드 역시 Java8부터 추가되었으며 접근 제어자는 public으로 생략 가능합니다.
static을 붙여 오버라이딩이 불가능하며 인스턴스를 생성하여 호출을 할 수 없고 클래스명.메소드명();으로 호출해야 한다.

인터페이스의 private 메소드

Java9에 대한 학습을 따로 하지 않아서 알지 못했던 부분인데 Java9부터 인터페이스에 private메소드와 private static 메소드를 사용할 수 있게 되었다.
인터페이스를 구현하는 클래스에 재정의하거나 사용할 수 없으며 default나 static 메소드를 통해서만 사용할 수 있다.

public interface Car {
    public abstract void printFuel();
    public abstract String getFuel();
    default void newMethod(){
        staticMethod();
    }
    private static void staticMethod(){
        System.out.println("static!");
    }
}

참고 문서

Java의 정석 - 남궁 성
http://www.tcpschool.com/java/intro
https://velog.io/@foeverna/Java-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%9A%94%EC%86%8C%EB%93%A4

'프로그래밍 > Java' 카테고리의 다른 글

예외처리  (0) 2021.01.13
조건문과 반복문  (0) 2021.01.11
연산자  (0) 2021.01.06
패키지  (0) 2021.01.02
데이터타입, 변수, 배열  (0) 2020.12.31