[JAVA]인터페이스

홍준표·2022년 11월 4일
0

java 스터디

목록 보기
8/8

목표

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


학습할 것

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

인터페이스 정의하는 방법

인터페이스란?

인터페이스는 일종의 추상클래스이다. 인터페이스는 추상클래스처럼 추상메서드를 가지지만 추상클래스보다 추상화의 정도가 높아서 몸통을 갖춘 일반 메서드 또는 멤버 변수를 구성원으로 가질 수 없다. 오직 추상 메서드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다.(jdk1.8이전)

추상클래스가 미완성 설계도라면, 인터페이스는 밑그림만 그려져 있는 기본 설계도라고 할 수 있다.

인터페이스를 작성하는 방법

인터페이스를 작성하는 것은 클래스를 작성하는 것과 동일하다. 단지 키워드로 class 대신 interface를 사용한다. 그리고 interface에도 클래스와 같이 접근제어자를 사용할 수 있다.

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

일반적인 클래스의 멤버들과는 달리 인터페이스의 멤버들은 제약사항이 있다.

  • 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
  • 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다. 단, static 메서드와 default 메서드는 예외(JDK 1.8부터)

생략된 제어자는 컴파일러가 자동적으로 추가해준다.

인터페이스 구현하는 방법

인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없다. 추상클래스가 상속을 통해 추상메서드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성해야 하는데 그 방법은 추상클래스와 같다. 단, 키워드 ‘extends’가 아닌 구현한다는 의미의 ‘implements’를 사용한다.

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

만일 구현하는 인터페이스의 메서드 중 일부만 구현한다면, abstract을 붙여서 추상클래스로 선언해야 한다.

	abstract class Soldier implements Fightable {
        public void move(int x, int y) { ... }
    }

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

	class Soldier extends Unit implements Fightable {
        public void move(int x, int y) { ... }
        public void attack(Unit u) { ... }
    }

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

다형성에 의해 자손클래스의 인스턴스를 조상타입의 참조변수로 참조하는 것이 가능하다는 사실을 알고 있다. 인터페이스 역시 해당 인터페이스의 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로의 형변환도 가능하다. 인터페이스 타입의 매개변수가 가지는 의미는 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야한다는 것이다.

인터페이스 Fightable 클래스 Fighter가 구현했을 때 , 다음과 같이 Fighter 인스턴스를 Fightable 타입의 참조변수로 참조하는 것이 가능하다. 물론 Fightable타입의 참조변수로는 인터페이스 Fightable에 정의된 멤버들만 호출이 가능하다.

Fightable f = (Fightable)new Fighter();
또는
Fightable f = new Fighter();

따라서 인터페이스는 메서드의 매개변수의 타입으로 사용될 수 있다.

void attack(Fightable f){
 ...
}

인터페이스 타입의 매개변수가 갖는 의미는 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 한다는 것이다.

그래서 attack메서드를 호출할 때는 매개변수로 Fightable 인터페이스를 구현한 클래스의 인스턴스를 넘겨주어야 한다.

즉, attack ( new Fighter() ) 와 같이 할 수 있다는 것이다.

class Fighter extends Unit implements Fightable {
	public void move(int x, int y) { /* 내용 생략 */}
	public void attack(Fightable f) { /* 내용 생략 */}
}

인터페이스 상속

인터페이스는 인터페이스로부터만 상속을 받을 수 있으며, 다중상속이 가능하다. 클래스의 상속과 마찬가지로 자손 인터페이스는 조상 인터페이스에 정의된 멤버를 모두 상속받는다.

	interface Movable {
        void move(int x, int y);
    }
    interface Attackable {
        void attack(Unit u);
    }
    interface Fightable extends Movable, Attackable { }

인터페이스는 클래스와 달리 Object클래스와 같은 최고 조상이 없다.

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

인터페이스에 메서드를 추가한다는 것은, 추상 메서드를 추가한다는 것이고, 이 인터페이스를 구현한 기존의 모든 클래스들이 새로 추가된 메서드를 구현해야 한다.
인터페이스가 변경되지 않으면 제일 좋지만, 언젠가는 변경이 발생하기 마련이다. 이를 해결하기 위해서 디폴트 메서드(default method)라는 것이 고안되었다. 디폴트 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로, 추상 메서드가 아니기 때문에 디폴트 메서드가 새롭게 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
디폴트 메서드는 앞에 키워드 default를 붙이며, 추상 메서드와 달리 일반 메서드처럼 몸통 { }이 있어야 한다. 접근 제어자는 public이며, 생략이 가능하다.

	interface MyInterface {
        void method();
        // void newMethod();  추상 메서드
        default void newMethod() { }
    }

추상 메서드를 추가하는 대신 디폴트 메서드를 추가하면 조상 클래스에 새로운 메서드를 추가한 것과 동일한 효과를 얻는다.

디폴트 메서드 충돌 규칙
새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌하는 경우 해결하는 규칙은 다음과 같다.

  • 여러 인터페이스의 디폴트 메서드 간의 충돌 ->
    인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.

  • 디폴트 메서드와 조상 클래스의 메서드 간의 충돌 ->
    조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

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

Java 8부터 인터페이스에 static 메서드 추가가 가능해졌다. 클래스에서 작성하는 방법과 동일하게 작성할 수 있고, 접근 제어자는 항상 public이며 역시 생략이 가능하다.

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

Java 9부터 사용할 수 있게된 private 메서드는 다음과 같은 특성을 가지고 있다.

  • 메서드의 몸통 { }이 있고 abstract이 아니다
  • 구현체에서 구현할 수 없고 자식 인터페이스에서 상속이 불가능하다.
  • static 메서드도 private이 가능하다.

private 메서드는 private, abstract, default 또는 static 메서드를 호출할 수 있다. private static은 static 및 static private 메서드만 호출 할 수 있다.

profile
프로그래밍 시작

0개의 댓글