JAVA의 정석

(객체part2 ) 10. 인터페이스(2) /디폴트 메서드와 static 메서드

499.token.required 2023. 9. 24. 18:33

원래 인터페이스에 추상 메서드만 선언할 수 있는데, JDK 1.8 부터 디폴트 메서드와 static 메서드도 추가할 수 있게 되었다.

 

static 메서드는 인스턴스와 관계없는 독릭적인 메서드이기 때문에 예전부터 인터페이스에 추가하지 못할 이유가 없었다.

 

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

 

메서드를 구현해야하기 때문이다. 인터페이스가 변경되지 않으면 제일 좋겠지만 아무리 설게를 잘해도 언젠가 변경은 발생하기 마련이다.

 

JDK의 설계자들은 고심 끝에 디폴트 메서드 라는 것을 고안해 내었다. 디폴트 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로 

 

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

 

디폴트 메서드는 앞에 키워드 default를 붙이며 , 추상 메서드와 달리 일반 메서드처럼 몸통 {} 이 있어야 한다.

 

디폴트 메서드 역시 접근 제어자가 public이며, 생략 가능하다.

 

interface Myinterface{

void method();

default void newmethod() {}

}

 

생성 방식은 이와 같다. 만약 여기서 default부분을 지우면 추상메서드라고 인식 되기 때문에 컴파일 오류가 생길 것이고, {}부분을 지우면

 

default메서드인데 구현을 안해주었기 때문에 컴파일 오류가 생길 것이다. 

 

위와 같이 추상메서드가 아닌, 디폴트 메서드를 추가해주면 기존의 Myinterface를 구현한 클래스를 변경하지 않아도 된다. 즉, 조상

 

클래스에 새로운 메서드를 추가한 것과 동일해 지는 것이다.

 

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

 

1. 여러 인터페이스 간의 충돌

 

- 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩해야한다.

 

2. 디폴트 메서드와 조상클래스의 메서드 간의 충돌

 

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

 

위의 규칙이 외우기 힘들다면, 그냥 필요한 쪽의 메서드와 같은 내용으로 오버라이딩 하면 된다.

 

예시는 다음과 같다.. 

 

 

1. 여러 인터페이스 간의 충돌

 

 

Myinterface , Myinterface 2를 구현하는 Child3클래스는 같은 이름의 메서드를 상속 받고 있다. 이 경우 상속 받은 클래스에서 

 

오버라이딩으로 구현해주면 컴파일 오류를 없앨 수 있다. 

 

class Child3 extends Parent3 implements MyInterface, MyInterface2 {

 

public void method1() {

System.out.println("method1() in MyInterface2");

}

 

}

 

여기서 중요한 점은 오버라이딩 할 때 상속받은 접근제어자보다 좁으면 안된다는 점을 잊지말자. 인터페이스의 method01 default라 써있

 

는 것은 접근제어자의 default 가아니기 때문에 (interface의 규칙. 모든 메서드는 public이어야한다.) public으로 오버라이딩 해주어야 

 

오류 뜨는 것을 피할 수 있다 .

 

 

 

2. 디폴트 메서드와 조상클래스의 메서드 간의 충돌

 

2번째 라인처럼, 상속과의 메서드와 인터페이스 구현의 메서드의 이름이 같다면 상속을 우선으로 하기에  Parent3의 메서드가 출력된 것을

 

볼 수 있다.  그리고 남은 MyInterface의 static 메서드 역시 정상적으로 출력되는 것을 볼 수 있다.  이로써 인터페이스의 장을 마치겠다.