자바의 인터페이스

2024. 2. 4. 13:49Java

반응형

인터페이스 (Interface) 란 무엇인가

인터페이스는 자바의 추상화 (abstraction) 개념을 구체화하기위한 산물이다.

클래스의 추상 메서드와 변수를 가지고 있고, 클래스와 IS-A 관계가 성립한다.

어떤 엔티티(실체)를 그것의 속성으로 표현하는 것이 아닌 행동(behavior)로 표현하고 싶다면 인터페이스를 사용한다.

인터페이스의 기본 문법

인터페이스를 정의하기 위해서는 인터페이스를 선언하고, 모든 구성요소를 추상화 해야한다.

즉, 인터페이스 내 모든 메서드는 구문이 존재하지 않아야하고 변수는 public, static 으로 선언되어 다중으로 상속할 수 있도록 해야한다. (이 부분은 JDK 8 이후 변화가 있음)

인터페이스를 상속하기 위해서는 implements 키워드를 사용하고 내부에 선언된 모든 메서드를 구현해야한다.

interface {
    // constant field
    // abstract method
}

인터페이스 구현체의 특징

  • 추상화 되어있다.
  • 클래스의 다중 상속은 허용되지 않지만, 인터페이스는 무제한 다중 상속 가능하다.
  • 코드 간 결합도가 낮다.

추상 클래스와의 차이점

추상 클래스 (abstract class) 는 final 이 아닌 변수를 가지고 있지만, 인터페이스의 변수는 public static final, 즉 상수이다.

interface Developer {
    final int id = 10;
    int coding();
}

인터페이스와 클래스 간 상속

  • Class extends Class : 가능
  • Class implements Interface : 가능
  • Interface extends Interface : 가능
  • Interface extends Class : 불가능

인터페이스와 클래스의 차이점

  • 인터페이스는 변수를 초기화하거나 객체 생성이 불가능하지만, 클래스는 변수 초기화와 객체 생성이 가능하다.
  • 인터페이스는 구현된 (implement) 고정된 (concrete) 메서드를 갖는 것이 불가능하지만, 클래스는 구현되고 고정된 메서드를 가질 수 있다.
  • 인터페이스는 public 접근 제어자만 가질 수 있지만, 클래스는 public, protected, private 접근 제어자를 가질 수 있다.

인터페이스 사용의 장점

  • 구현 부분의 코드를 추상화하여 감출 수 있다.
  • 객체 지향의 개념 특성상 다중 상속이 불가능하나, 인터페이스를 사용하면 다중 상속이 가능하다.
public interface DevInterface1 {
    int dev1 = 10;

    void method1(int a);
    void method2(int b);

    // 기본 구현 메서드 정의 가능 (JDK 8 이후)
    default void method5() {
        System.out.println("default interface method");
    }
}

public interface DevInterface2 {
    void method3(int c);
    void method4(int d);

    // 정적 기본 메서드 구현 가능 (JDK 8 이후)
    static void method6() {
        System.out.println("static method");
    }
}

public interface DevInterface3 extends DevInterface1, DevInterface2 {
    // 다중 상속, 이중 상속 가능
    void method7();
}

public class DevClass1 implements DevInterface1, DevInterface2 {
    // 메서드 구현
    @Override
    public void method1(int a) {
        System.out.println(a);
    }

    @Override
    public void method2(int b) {
        System.out.println(b);
    }

    // 다중 상속
    @Override
    public void method3(int c) {
        System.out.println(c);
    }

    @Override
    public void method4(int d) {
        System.out.println(d);
    }

    public static void main(String[] args) {
        DevClass1 dc1 = new DevClass1();
        dc1.method1(1); // 1
        dc1.method2(2); // 2
        dc1.method3(3); // 3
        dc1.method4(4); // 4
        dc1.method5(); // default interface method
        DevInterface2.method6(); // static method
    }
}

public class DevClass2 implements DevInterface1 {
    // 다른 구현
    @Override
    public void method1(int a) {
        System.out.println(a + 1);
    }

    @Override
    public void method2(int b) {
        System.out.println(b + 1);
    }

    public static void main(String[] args) {
        DevClass2 dc2 = new DevClass2();
        dc2.method1(1); // 2
        dc2.method2(2); // 3
    }
}

public class DevClass3 implements DevInterface3 {
    @Override
    public void method1(int a) {
        System.out.println(a);
    }

    @Override
    public void method2(int b) {
        System.out.println(b);
    }

    @Override
    public void method3(int c) {
        System.out.println(c);
    }

    @Override
    public void method4(int d) {
        System.out.println(d);
    }

    @Override
    public void method7() {
        System.out.println("method 7");
    }

    public static void main(String[] args) {
        DevClass3 dc3 = new DevClass3();
        dc3.method1(1); // 1
        dc3.method2(2); // 2
        dc3.method3(3); // 3
        dc3.method4(4); // 4
        dc3.method7(); // method 7
    }
}

코드 추상화 구현의 단계

  • 인터페이스에는 여러 개의 추상 메서드를 만들어 둘 수 있다.
  • 만약 인터페이스에 있는 모든 추상 메서드를 구현할 수 없다면, 추상 클래스로 일부를 구현하고 본 클래스에 구현의 책임을 넘길 수 있다.
  • 그 후 상속받은 클래스에서 모든 메서드를 구현한다.
  • 구현된 코드를 main() 메서드에서 실행한다.
public interface Dev2Interface {
    void method1();
    void method2();
    void method3();
    void method4();

    // JDK 9 이후 private, static 메서드 사용 가능
    // default 메서드에서 private 실행 가능
    default void method8() {
        System.out.println("default method");
        method6();
    }

    // static 메서드에서 private static 실행 가능
    static void method5() {
        System.out.println("static method");
        method7();
    }

    // private 메서드는 default 메서드에서 사용 가능
    private void method6() {
        System.out.println("private method");
    }

    // private static 메서드는 static 메서드에서 사용 가능
    private static void method7() {
        System.out.println("private static method");
    }
}

abstract class Dev2AbClass1 implements Dev2Interface {
    @Override
    public void method1() {
        System.out.println("method1 on abstract class 1");
    }
}

abstract class Dev2AbClass2 extends Dev2AbClass1 {
    @Override
    public void method2() {
        System.out.println("method 2 on abstract class 2");
    }
}

public class Dev2Class extends Dev2AbClass2{
    @Override
    public void method3() {
        System.out.println("method 3");
    }

    @Override
    public void method4() {
        System.out.println("method 4");
    }

    public static void main(String[] args) {
        // 인스턴스 생성
        Dev2Class d2c = new Dev2Class();
        // 상속 메서드
        d2c.method1(); // method1 on abstract class 1
        d2c.method2(); // method2 on abstract class 2
        // 구현 메서드
        d2c.method3(); // method3
        d2c.method4(); // method4

        // static 메서드
        Dev2Interface.method5(); // static method, private static method

        // default 메서드
        d2c.method8(); // default method, private method
    }
}

정리

  • 인터페이스는 자체적으로 객체를 생성해 낼 수는 없지만, 클래스에서 구현(implements) 할 수 있다.
  • 클래스는 복수의 인터페이스를 구현할 수 있다.
  • 인터페이스는 다수의 인터페이스를 상속받을 수 있다.
  • 인터페이스를 상속한 클래스는 인터페이스 내 모든 메서드를 구현해야 한다.
  • JDK 8, 9 이후에는 변화가 있지만 기본적으로 메서드는 public abstract 즉 공개, 비어있음. 변수는 public static final 즉 상수
  • 클래스는 못하는 다중 상속을 할 수 있다.
  • 코드가 추상화되어 있으므로 결합도가 낮아진다.
  • 인터페이스 내의 변수는 상수이므로 인스턴스 변수는 선언할 수 없다.
  • 인터페이스에서는 생성자 (Constructor) 를 사용할 수 없다.
  • 인터페이스에서는 main() 메서드를 사용할 수 없다.

Resources

반응형

'Java' 카테고리의 다른 글

자바의 다형성  (0) 2024.02.04
자바의 상속  (0) 2024.02.04
자바의 패키지  (0) 2024.02.02
자바의 클래스(Class)와 객체(Object)  (1) 2024.02.01
자바와 자료구조  (0) 2024.01.30