뭐라도 끄적이는 BLOG

Java Interface 본문

Java/Java 기본

Java Interface

Drawhale 2023. 7. 2. 05:07

인터페이스란?

인터페이스는 구체적인 방법을 직접적으로 기술하지 않고 전체적인 모습을 볼 수 있는 설계도라고 할 수 있다.

인터페이스 사용의 이유

  1. 개발 기간을 단축 시킬 수 있다.
  2. 인터페이스를 사용하면 다른 개발자들이 각각의 부분을 완성할 때까지 기다리지 않고 서로 규약만 정해두어 각자의 부분만 따로 나눠서 작성된 코드를 컴파일 할 수 있다.
  3. 클래스간 결합도를 낮출 수 있다.
  4. 코드의 종속성을 줄이고 유지보수성을 높이도록 해준다.
  5. 표준화가 가능하다.
  6. 클래스의 기본틀을 제공하여 개발자들에게 정형화된 개발을 강요할 수 있다. 자바의 다형성을 극대화 하여 코드의 수정을 줄이고 마찬가지로 유지보수성을 높인다.

인터페이스 정의하는 방법

public interface 인터페이스{
    public static final 타입 상수이름 = 값;
    public abstract 메서드이름(매개변수목록);
}

기존에 클래스에서 class 키워드 대신 interface 키워드를 사용한다. 접근제어자는 공용API를 정의하는것 이기 때문에 암시적으로 public이므로 생략이 가능하다. 인터페이스에서 선언한 모든 변수는 public static final 키워드가 자동으로 붙는다. 메서드는 public abstract가 자동으로 붙는다.

  • Java8부터 static method와 default method를 사용할 수 있다.
  • Java9부터 private methods를 사용할 수 있다.

인터페이스는 추상 클래스와 같이 인스턴스를 생성할 수 없고, implements한 클래스에서 구현한 뒤 자식 클래스를 인스턴스화 하여 사용한다.

인터페이스 구현하는 방법

인터페이스는 class에 implements 키워드를 사용하여 구현할 수 있습니다. 인터페이스는 extends와 다르게 다중 implements를 할 수 있다.

class 클래스 이름 implements 인터페이스 이름 {
    //인터페이스의 추상메서드 구현
}

구현하는 인터페이스의 메서드중 일부만 구현한다면 일반클래스가 아닌 추상클래스로 선언해야 한다.

abstract class 클래스 이름 implements 인터페이스 이름 {
    //인터페이스의 추상메서드 구현
}

상속과 구현을 동시에 할 수 있다.

abstract class 자식 클래스 이름 extends 부모 클래스 이름 implements 인터페이스 이름 {
    //인터페이스의 추상메서드 구현
}

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

예시로 Animal 인터페이스를 만들고 Animal인터페이스로 구현한 Cat과 Dog 클래스

public interface Animal {
    String getName();
}
public class Cat implements Animal {
    @Override
    public String getName(){
        return "고양이";
    }
}
public class Dog implements Animal {
    @Override
    public String getName(){
        return "개";
    }
}

cat과 dog 인스턴스는Animal 타입으로 생성 가능하다.

Animal cat = new Cat();
Animal dog = new Dog();

Animal인터페이스를 파라미터로 받는 메소드의 파라미터에 Animal 인터페이스를 구현한 Cat과 Dog인스턴스를 사용할 수 있다.

public void printName(Animal animal){
    System.out.printlne("이름: " + animal.getName());
}

Animal cat = new Cat();
Animal dog = new Dog();

printName(cat);
printName(dog);

인터페이스 상속

인터페이스는 다른 인터페이스를 상속할 수 있다. 클래스와 동일하게 extends 키워드를 사용하여 인터페이스를 상속 할 수 있다.

public interface Bird extends Animal {
    public bool getFly();
}
class Penguin implements Bird{

    @Override
    public String getName() {
        return "팽귄";
    }

    @Override
    public boolean getFly() {
        return false;
    }
}

Bird의 구현체를 만들면 Bird의 부모 인터페이스인 Animal 인터페이스의 메소드도 구현해야 한다. 클래스는 단 하나의 클래스만 상속이 가능하지만 인터페이스는 여러 인터페이스를 상속할 수 있다.

public interface Habitat {
}
public interface Bird extends Animal, Habitat{
    boolean getFly();
}

이렇게 여러 인터페이스를 구현한 Penguin클래스는 Animal, Habitat타입으로 인스턴스화가 가능하다.

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

Java8부터 default method가 생겨 구현을 포함하는 메소드를 인터페이스에서 정의할 수 있다.

Animal 인터페이스에서 Animal구현체의 정보를 출력할 수 있도록 print메소드를 정의할 수 있는데 이때 구현체마다 매번 따로 구현할 필요가 없다고 생각되면 default method로 정의하여 사용할 수 있다.

public interface Animal {
    String getName();
    default void print(){
        System.out.println("이름: " + getName());
    }
}

default 키워드를 사용하여 기본 메소드를 구현할 수 있고 기본 메소드는 구현체에서 필수로 구현할 필요가 없다.

 

Default method는 구현체에서 필수적으로 구현할 필요가 없기 때문에 하위 호환이 가능하다. 이전에 Animal 인터페이스에서 새로운 기능이 추가 되어야 한다면 메소드 정의후 각 구현체에서 구현을 따로 해주거나 인터페이스를 래핑하는 클래스가 필요했지만 기본 메소드로 구현한다면 인터페이스의 구현체들에게 영향이 없다.

 

주의 사항

한 클래스에서 두 인터페이스를 구현하는데 각 인터페이스에 같은 시그니쳐의 기본 메소드가 정의 되어 있을수도 있다.

public interface Animal {
    String getName();
    default void print(){
        System.out.println("이름: " + getName());
    }
}
public interface TerrestrialLife {
    String getEnvironment();
    default void print(){
        System.out.println("환경: " + getEnvironment());
    }
}

해당 문제는 컴파일 타임에서 발견할 수 있으며 print메소드를 직접 구현해야한다. 이때 각각의 인터페이스의 메소드를 사용할 수도 있으며 따로 정의하는 방법도 있다.

public class Dog implements Animal, TerrestrialLife {
    @Override
    public String getName(){
        return "개";
    }
    
    @Override
    public void print() {
        Animal.super.print(); // Animal print() 메소드 호출
        TerrestrialLife.super.print(); // TerrestrialLife print() 메소드 호출
        // 혹은 직접 구현...
    }
}

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

java8 부터 인터페이스에 static 메소드도 추가가 가능하다. 접근 지시자는 클래스의 static 메소드와 같이 기본적으로 public이다. static 메소드이므로 상속이 불가능하다.

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

java9부터 사용할 수 있는 메소드로 java8에서 기본메소드 사용이 가능해졌기 때문에 로직을 분리하는 용도로 사용할 수 있다.

  • private메소드는 인터페이스에서 구현이 되어 있어야하고 abstract메소드일 수 없다.
  • 구현체에서 구현할 수 없고 자식 인터페이스에서도 상속이 불가능하다.
  • static메소드도 private가 가능하다.
반응형

'Java > Java 기본' 카테고리의 다른 글

Java Thread  (0) 2023.07.02
Java Exception, Error  (0) 2023.07.02
Java 패키지  (0) 2023.07.02
Java 상속(Inheritance)  (0) 2023.07.02
Java Class  (0) 2023.07.01