목표
자바의 인터페이스에 대해 학습하세요.
학습할 것 (필수)
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메소드 (Default Method), 자바 8
- 인터페이스의 static 메소드, 자바 8
- 인터페이스의 private 메소드, 자바 9
#인터페이스 정의하는 방법
인터페이스란?
일종의 추상클래스, 추상 클래스처럼 추상 메서드를 갖지만 추상 클래스보다 추상화 정도가 높아서 추상 클래스와 달리 몸통을 갖춘 일반 메서드, 멤버 변수를 구성원으로 가질 수 없다.
추상 클래스 = 미완성 설계도 / 인터페이스 = 밑그림만 그려진 기본 설계도
class 대신 interface라는 키워드를 이용하여 선언할 수 있으며 메서드 시그니처와 상수 선언만을 포함할 수 있다.

인터페이스 장점
1. 개발 시간 단축
인터페이스가 작성되면 이를 사용해서 프로그램을 작성하는 것이 가능
메서드를 호출하는 쪽에서는 선언부만 알면 되기 때문
2. 표준화 기능
프로젝트에 사용되는 기본 틀을 인터페이스로 작성한 다음, 개발자들에게 인터페이스를 구현하여 프로그램을 작성하도록 하면 보다 일관되고 정형화된 프로그램 개발이 가능
3. 서로 관계 없는 클래스들 간의 관계를 맺어준다
하나의 인터페이스를 공통적으로 구현하도록 하여 관계를 맺어줄 수 있다.
4. 독립적인 프로그래밍이 가능
인터페이스를 이용하면 클래스의 선언과 구현을 분리시킬 수 있기 때문에 실제 구현에 독립적인 프로그램을 작성하는 것이 가능
인터페이스의 작성
인터페이스를 작성하는 것은 클래스를 작성하는 것과 같다. 다만 키워드로 class 대신 interface를 사용하는 것만 다르다.
그리고 interface에도 클래스와 같이 접근제어자로 public 또는 default를 사용할 수 있다.
interface
인터페이스 이름{
public static final 타입 상수 이름 = 값;
public abstract 메서드이름( 매개변수 목록);
}
일반적인 클래스의 멤버들과 달리 인터페이스의 멤버들은 제약사항이 있다
- 모든 멤버 변수는 public static final(상수) 이어야 하며 이를 생략할 수 있다.
(인터페이스의 모든 멤버에 공통 사항이라 생략 가능, 컴파일 시 컴파일러가 자동적으로 추가해줌)
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.(단, static 메서드와 디폴트 메서드는 예외)
#인터페이스 구현하는 방법
인터페이스의 구현
인터페이스도 추상 클래스처럼 그 자체로는 인스턴스를 생성할 수 없다.
추상 클래스가 상속을 통해 추상 메서드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상 메서드의 몸통을 만들어주는 클래스를 작성해야 하는데 그 방법은 추상 클래스가 자신을 상속받는 클래스를 정의하는 것과 다르지 않다.
class 클래스 이름 implements 인터페이스 이름{
//인터페이스에 정의된 추상 메서드를 구현해야 한다.
}
class Fighter implements Fightable{
public void move(int x, int y) { }
public void attack(Unit u) { }
}
클래스는 확장한다는 의미의 키워드 'extends'를 사용하지만 인터페이스는 구현한다는 의미의 키워드 'implement'를 사용한다.
구현하는 인터페이스의 메서드 중 일부만 구현한다면 abstract를 붙여서 추상 클래스로 선언해야 한다.
※인터페이스의 이름에는 주요 Fightable과 같이 "~을 할 수 있는 의미인 'able'로 끝나는 것들이 많은데, 그 이유는 어떠한 기능 또는 행위를 하는데 필요한 메서드를 제공한다는 의미를 강조하기 위해서다. 또한 그 인터페이스를 구현한 클래스는 '~를 할 수 있는'능력을 갖추었다는 의미이기도 하다.
인터페이스의 다중 구현

객체는 다수의 인터페이스 타입으로 사용할 수 있다.
인터페이스 A와 인터페이스 B가 객체의 메서드를 호출할 수 있으려면, 객체는 이 두 인터페이스 모두를 구현해야 한다.
다중 인터페이스를 구현할 경우 구현 클래스는 모든 인터페이스의 추상 메서드에 대해 실체 메서드를 작성해야 한다.
public class 구현 클래스 implements 인터페이스A, 인터페이스B{
//인터페이스 A의 추상 메서드 실체 메서드 선언
//인터페이스 A의 추상 메서드 실체 메서드 선언
}
#인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
1. 인터페이스 생성

2. 인터페이스 구현

3.main메서드 내에서 사용

출력

인터페이스는 구현체를 통해서 인스턴스 생성이 가능하다.
dog.name()을 사용 못하는 이유는 캐스팅을 안 해줘서 사용을 못한다.
(Dog)dog.name()으로 캐스팅하여 사용할 수 있다.
#인터페이스 상속
인터페이스의 상속
인터페이스는 인터페이스로부터만 상속받을 수 있으며(Object가 최고 조상이 아님), 클래스와는 달리 다중 상속이 가능하다(추상 메서드는 충돌해도 문제없음). 클래스의 상속과 마찬가지로 자손 인터페이스는 조상 인터페이스에 정의된 멤버를 모두 상속받는다.
그래도 자손 인터페이스 자체에는 정의된 멤버가 하나도 없지만 조상 인터페이스로부터 상속받은 멤버들을 자신의 멤버로 갖게 된다
인터페이스의 다형성
인터페이스 타입의 참조 변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로의 현변 환도 가능하다.
ex) Fightable f = (fightable)new fighter(); 또는 Fightable f = new Fighter();
따라서 인터페이스는 void attack(Fgitable f) {...}와 같이 매개변수의 타입으로 사용될 수 있다.
인터페이스 타입의 매개변수가 갖는 의미는 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 한다는 것이다.
그래서 attack 메서드를 호출할 때는 매개변수로 Fightable 인터페이스를 구현한 클래스의 인스턴스를 넘겨주어야 한다.(Fightable 인터페이스를 구현한 Fighter 클래스의 멤버)
Fightable 인터페이스를 구현한 Fight 클래스가 있을 때, attack메서드의 매개변수로 Fighter 인스턴스를 넘겨줄 수 있다. attack(newFighter())와 같이 할 수 있다는 것이다.
Fightable method() {
...
Fighter f = new Fighter();
retufn f;
}
다음과 같이 메서드의 리턴 타입으로 인터페이스의 타입을 지정하는 것도 가능하다.
리턴 타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
#인터페이스의 기본 메소드 (Default Method), 자바 8
기본 구현을 가지는 메서드 앞에 default 예약어를 붙이며, 추상 메서드와 달리 일반 메서드처럼 몸통{ }이 있어야 한다.
접근제어자가 public이며 생략 가능하다. 디폴트 메서드는 인터페이스에 이미 구현되어 있으므로 인터페이스를 구현한 클래스에서 코드를 구현할 필요가 없다. 단, 구현하는 클래스에서 재정의 할 수 있다.
인터페이스가 default키워드로 선언되면 메서드가 구현될 수 있다. 또한 이를 구현하는 클래스는 default메서드를 오버 라이딩할 수 있다.

인터페이스가 변경이 되면, 인터페이스를 구현하는 모든 클래스들이 해당 메서드를 구현해야하는 문제가 있다.
이런 문제를 해결하기 위하여 인터페이스에 메서드를 구현해 놓을 수 있도록 하였다.
#인터페이스의 static 메소드, 자바 8
Java8부터 interface에 static메서드를 선언할 수 있게 되었다.
인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메서드다.
static예약어를 사용하며, 접근제어자는 항상 public이며 생략할 수 있다.
정적 메서드를 사용할 때는 인터페이스를 직접 참조하여 사용한다.

단, static 메서드를 사용하는데 주의해야 할 점은 기존 클래스의 static 메서드처럼 class이름. 메서드로 호출하는게 아니라
interface이름.메서드로 호출해야 한다는 것이다.

인터페이스의 default, static 메서드가 등장하면서 추상클래스의 의미가 없어지는 것이 아닌가 생각할 수 있지만, 인터페이스에서는 추상클래스 처럼 상수외의 변수를 선언할 수 없다. 추상클래스의 많은 요소들을 java8부터 인터페이스에 구현할 수있지만 추상클래스에서만 할 수 있는 것들이 있기 때문에, 추상클래스 자체의 효용가치는 아직 존재한다.
#인터페이스의 private 메소드, 자바 9
java8에서는 default 메서드와, static메서드가 추가되었는데,
java9에서는 추가적으로 private 메서드와 private static메서드가 추가되었다
private 메서드가 생긴 이유
-java8의 default메서드와 static메서드는 여전히 불편하게 만든다
-단지 특정 기능을 처리하는 내부 메서드일 뿐인데도, 외부에 공개되는 public메서드로 만들어야 하기 때문
-인터페이스를 구현하는 다른 인터페이스 혹은 클래스가 해당 메서드에 액세스 하거나 상속할 수 있는 것을 원하지 않지만, 그렇게 될 수 있는 것이다.
private 메서드의 4가지 규칙
1. private 메서드는 구현부를 가져야 한다
2. 오직 인터페이스 내부에서만 사용할 수 있다.
3. private static 메서드는 다른 static 또는 static이 아닌 메서드에 사용할 수 있다.
4. static이 아닌 private 메서드는 다른 private static 메서드에서 사용할 수 없다.
java9에서 private메서드, private static 메서드라는 새로운 기능을 제공함으로써 코드의 중복을 피하고 인터페이스에 대한 캡슐화를 유지할 수 있게 되었다.
'Back-end > Java_T.I.L' 카테고리의 다른 글
| [TIL 220107] 자바의정석 6. 객체지향 프로그래밍 I (1) (0) | 2022.01.08 |
|---|---|
| 9. 예외처리 (0) | 2022.01.06 |
| 7.패키지, import, 클래스패스(classpath) (0) | 2022.01.05 |
| 6. 상속, 오버라이딩, 추상클래스, Object 클래스 (0) | 2022.01.03 |
| 5. 클래스 (2) | 2022.01.02 |
댓글