JAVA Interface

‍박소연·2025년 5월 16일

인터페이스란?

일종의 추상클래스로, 구현해야할 메소드의 분할이 필요하거나 클래스들에게 다중상속이 필요할 때 인터페이스를 사용한다.

  • 오직 추상 메서드와 상수만을 멤버로 갖는다.

인터페이스의 작성

interface intef1 {
	public static final type val1;
    public abstract method1
}
  • 모든 멤버 변수는 public static final 이어야 하며, 이를 생략할 수 있다.
  • 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.

인터페이스의 상속

인터페이스로부터만 상속받을 수 있으며, 클래스와는 달리 다중상속이 가능하다.

인터페이스의 다중 상속

자바에서는 다중 상속을 허용하지 않는다

두 조상으로 상속받는 멤버 중에서 멤버 변수의 이름이 같거나 메서드의 선언부가 일치하고 구현부만 다르다면 어느 조상의 것을 상속받게 되는 것인지 알 수 없다.


인터페이스의 구현

인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없으며, 자신에 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성해야 한다.


  • 인터페이스는 추상 메서드를 구현한다는 의미로 implements 키워드를 사용한다.
	class clsName implements interf1 {
    	// 인터페이스에 정의된 추상메서드 구현
    }

  • 만일 구현하는 인터페이스의 메서드 중 일부만 구현한다면, abstract를 붙여서 추상클래스로 선언해야 한다.
	abstract class clsName implements interf1 {
    	// 인터페이스에 정의된 추상메서드 일부만 구현
    }

인터페이스의 다형성

자손 클래스의 인스턴스를 조상 타입의 참조 변수로 참조하는 것이 가능한 것처럼, 인터페이스 타입의 참조 변수로 그 인터페이스를 구현한 클래스의 인스턴스를 참조할 수 있다.

  /*Fightable 타입의 참조 변수로는 Fightable에 정의된 멤버들만 호출 가능하다.*/
	Fightable f = new Fighter();
  • 따라서 인터페이스는 메서드의 매개변수의 타입으로 사용될 수 있다.
	void attack(Fightable f) {...}

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

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

default 메서드

상수와 추상 메서드만 포함할 수 있었던 인터페이스에 기본적인 구현 내용을 포함할 수 있게 하는 메서드이다.

인터페이스에 메서드 추가

인터페이스에 메서드를 추가한다는 것은, 추상 메서드를 추가한다는 것이고, 이 인터페이스를 구현한 기존의 모든 클래스들이 새로 추가된 메서드를 구현해야 한다.


그러나, 디폴트 메서드는 추상 메서드의 구현을 제공하기 때문에 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.

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

조상 클래스에 새로운 메서드를 추가한 것과 비슷한 역할을 한다.

디폴트 메서드 중복 문제

새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌하는 경우가 있다.

  1. 여러 인터페이스의 디폴트 메서드 간의 충돌
  • 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야 한다.
  1. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
  • 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.

연습 문제

Q1

  interface Movable {
      void move() {
          System.out.println("움직인다");
      }
  }

인터페이스의 메서드는 기본적으로 public abstract 입니다. 즉, 인터페이스에서는 구현부를 구현할 수 없습니다.

defalut 메서드 사용하면 구현부 구현 가능

Q2

    interface Drivable {
      void drive();
  }

  class Car implements Drivable {
  }

Car 클래스가 interface인 Drivable의 추상 메서드를 구현하지 않았다.

Car도 abstract 클래스 이거나 drive()를 구현해야 한다.

0개의 댓글