[Java/문법] 인터페이스
1. 인터페이스 역할 및 사용 이유
1-1) 역할
- 객체의 사용 방법을 정의한 타입이다. 인터페이스는 객체의 교환성을 높여주기 때문에 다형성을 구현하는 매우 중요한 역할을 한다.
- 자바 8의 람다식은 함수적 인터페이스의 구현 객체를 생성하기 때문에 더욱 중요해졌다.
- 인터페이스는 개발 코드와 객체가 서로 통신하는 접점 역할을 한다. 개발 코드가 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출한다. 그렇기 때문에 개발 코드는 객체의 내부 구조를 알 필요가 없고, 인터페이스의 메소드만 알면 된다.
1-2) 사용 이유
- 개발 코드가 직접 객체의 메소드를 호출하면 간단한데 왜 중간에 인터페이스를 두냐면, 개발 코드를 수정하지 않고 사용하는 객체를 변경할 수 있도록 하기 위함이다.
- 인터페이스는 하나의 객체가 아니라 여러 객체들과 사용이 가능하므로, 어떤 객체가 사용하느냐에 따라 실행 내용과 리턴값이 다를 수 있다.
- 따라서 개발 코드 측면에서는 코드 변경 없이 실행 내용과 리턴값을 다양화할 수 있다는 장점이 있다.
1-3) 구성
- 클래스는 필드, 생성자, 메소드를 구성 멤버로 가지는 반면에, 인터페이스는 상수와 메소드만을 구성 멤버로 가진다.
- 자바 7 이전엔 실행 블록 없는 추상 메소드만 선언이 가능했지만, 자바 8이후 디폴트 메소드, 정적 메소드도 선언 가능해졌다.
1-3-1) 추상 메소드 선언
- 추상 메소드는 리턴 타입, 메소드명, 매개변수만 기술되고 { }는 붙이지 않는 메소드이다.
- 인터페이스에 선언된 추상 메소드는 모두 public abstract 특성을 갖기 때문에 public abstract를 생략하더라도 자동적으로 컴파일 과정에 붙는다.
1-4) 인터페이스 작성 예시
1-5) 인터페이스 구현 클래스 예시
- 구현 클래스에서 추상 메소들에 대한 실체 메소드를 작성할 때 주의할 점은 인터페이스의 모든 메소드는 기본적으로 public 접근 제한을 갖기 때문에 public보다 낮은 접근 권한으로 작성할 수 없다.
- public을 생략하면 "Cannot reduce the visibility of the inherited method"라는 컴파일 에러가 나온다.
1-6) 익명 구현 객체
- 일회성의 구현 객체를 만들기 위해 소스 파일을 만들고 클래스를 선언하는 것은 비효율적이다. 자바는 소스 파일을 만들지 않고도 구현 객체를 만들 수 있는 방법을 제공하는데, 그것이 익명 구현 객체이다.
1-7) 다중 인터페이스 구현 클래스
- 인터페이스는 다중 구현이 가능하다. 다중 인터페이스를 구현할 경우 구현 클래스는 모든 인터페이스의 추상 메소드에 대해 실체 메소드를 작성해야 한다. 만약 하나라도 없다면 추상 클래스로 선언해야 한다.
1-8) 인터페이스 사용
- 인터페이스는 참조 타입이기 때문에 구현 객체가 대입될 경우 구현 객체의 번지를 저장한다.
1-8-1) 추상 메소드, 디폴트 메소드 사용
1-9) 타입 변환과 다형성
1-9-1) 자동 타입 변환
- 인터페이스 변수 = 구현 객체
- 자동 타입 변환을 이용하면 필드의 다형성과 매개 변수의 다형성을 구현할 수 있다. 필드와 매개 변수의 타입을 인터페이스로 선언하면, 여기에 다양한 구현 객체를 대입해서 실행 결과를 다르게 할 수 있다.
1-9-2) 필드의 다형성
1-9-3) 매개변수의 다형성
1-10) 디폴트 메소드의 필요성
- 기존 인터페이스를 확상해서 새로운 기능을 추가하기 위해서이다.
- 기존 인터페이스의 이름과 추상 메소드의 변경 없이 디폴트 메소드만 추가할 수 있기 때문에 이전에 개발한 구현 클래스를 그래도 사용할 수 있고, 새롭게 개발하는 클래스는 디폴트 메소드를 활용할 수 있다.
- ex