백기선 자바 스터디 1기 8주차

2023. 10. 19. 02:31Java/java-live-study

728x90
반응형

목표

자바의 인터페이스에 대해 학습하세요.

학습할 것

  • 인터페이스 정의하는 방법
  • 인터페이스 구현하는 방법
  • 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
  • 인터페이스 상속
  • 인터페이스의 기본 메소드 (Default Method), 자바 8
  • 인터페이스의 static 메소드, 자바 8
  • 인터페이스의 private 메소드, 자바 9

인터페이스 정의하는 방법

인터페이스는 일종의 추상 클래스이다. 단, 추상 클래스보다 추상화 정도가 높아서 추상 클래스와 달리 일반 메소드 또는 멤버변수 멤버로 가질 수 없다. 오직 추상 메소드(abstract)와 상수(final)만을 멤버로 가질 수 있다.

 

※ 자바 8버전부터 default 예약어를 통해 일반 메소드 구현이 가능하다.

 

인터페이스는 다음과 같이 정의가 가능하다.

interface Programming { //interface (인터페이스 이름)

    int a = 0; //public static final 이 숨어있다.
    void coding(); //public abstract 가 숨어있다.
}

인터페이스 구현하는 방법

인터페이스는 implements 예약어로 해당 인터페이스를 구현(상속)하고있는 클래스에서 구현이 가능하다. 클래스에서 인터페이스에서 정의한 추상 메서드를 재정의하면 된다.

interface Programming {

    int a = 0;
    void coding();
}

class Hong implements Programming { //implements 예약어로 구현(상속)

    @Override
    public void coding() { //재정의
        System.out.println("코오오오오딩");
    }
}

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

클래스 상속에서의 다형성이 인터페이스로도 가능하다. 인터페이스 레퍼런스로도 Dynamic Method Dispatch가 일어난다.

interface Programming {

    void coding();
}

class Hong implements Programming {

    @Override
    public void coding() {
        System.out.println("CPP programming");
    }
}

class Lee implements Programming {

    @Override
    public void coding() {
        System.out.println("python programming");
    }
}

public class InterfaceTest {

    public static void main(String[] args) {
        List<Programming> programmingList = Arrays.asList(new Hong(), new Lee());
        programmingList.forEach(p->p.coding());
    }
}

인터페이스 상속

인터페이스의 상속은 클래스 상속과는 다르게 다중상속이 가능하다.

interface Programming {

    void coding();
}

interface debugging {

    void debug();
}

class Hong implements Programming, debugging {

    @Override
    public void coding() {
        System.out.println("programming");
    }
    
    
    @Override
    public void debug() {
        System.out.println("debug code...");
    }
}

 

하지만 다음과 같이 리턴값만 다른 메서드를 가지고 있는 인터페이스들을 상속 받으면 컴파일 에러가 발생한다.

interface JavaProgramming {

    boolean coding(); //return boolean
}

interface CPPProgramming {

    void coding(); //return void
}

class Hong implements JavaProgramming, CPPProgramming {


    @Override
    public void coding() { //error
        
    }
}

인터페이스의 기본 메소드 (Default Method), 자바 8

인터페이스는 기능에 대한 선언만 가능하기 때문에 기능을 구현한 코드는 포함될 수 없었다.

하지만 Java8에서 부터 이러한 규칙에 반하는 기능이 나왔는데, 그것이 default method이다.

메소드 선언시 default를 명시하게 되면 인터페이스 내부에도 구현부를 작성할 수 있다.

interface Programming {

    void coding();

    default void learnJava() {
        System.out.println("learning...");
    }
}

 

default 메소드는 왜 등장했을까?

 

하위호환성 때문이다. 예를 들어 내가 사용하는 오픈소스의 인터페이스에 새로운 메소드를 만들어야하는 상황이 발생하여 오픈소스 개발자가 인터페이스에 메소드를 추가하게 된다면 나는 내 코드의 해당 인터페이스를 상속 받는 모든 구현체에 새로운 메소드를 오버라이팅해주어야 한다.

 

하지만 이때 오픈소스 개발자가 default 키워드를 사용하여 메소드를 추가하면 나는 코드의 수정 해당 오픈소스를 잘 사용할 수 있을 것이다.


인터페이스의 static 메소드, 자바 8

인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메소드이다.

interface Programming {

    static void hello() {
        System.out.println("hello...");
    }
}

public class Main {

    public static void main(String[] args) {
        Programming.hello();
    }
}

인터페이스의 private 메소드, 자바 9

Java9에서는 인터페이스 내에 private 메소드를 구현할 수 있게 되었다.

그 이유는 Java8에서 default 나 static 메소드를 구현할때 특정 기능을 처리하는 내부 메소드일 뿐인데도 외부에 공개되는 public 메소드로 만들어야하기 때문이다.

interface Programming {

    default void defaultHello() {
        doSomethingDefault();
        doSomethingStatic();
    }
    
    private void doSomethingDefault() {
        System.out.println("do something default...");
    }
    
    static void staticHello() {
        doSomethingStatic();
    }

    private static void doSomethingStatic() {
        System.out.println("do something static...");
    }
}

 

728x90
반응형