목표
자바의 인터페이스에 대해 학습하세요.
학습할 것 (필수)
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메소드 (Default Method), 자바 8
- 인터페이스의 static 메소드, 자바 8
- 인터페이스의 private 메소드, 자바 9
인터페이스 정의하는 방법
클래스 작성법과 같다. 다만 키워드로 class 대신 interface를 사용한다.
interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 메서드이름 (매개변수목록);
}
인터페이스 멤버 제약사항
- 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
- 모든 메서드는 public abstract 이어야하며, 이를 생략할 수 있다. (단, static메서드와 디폴트 메서드는 예외)
인터페이스 구현하는 방법
implements 키워드를 사용하여 클래스에서 추상메서드를 작성하는 것을 구현한다고 한다.
class 클래스이름 implements 인터페이스이름{
// 인터페이스에 정의된 추상메더드 구현
}
ex)
class Fighter implements Fightable{
public void move(int x, int y) { /*내부 구현*/}
public void attack(Unit U) {/*내부 구현*/}
}
ex2) // 상속과 구현을 동시에 하는 경우
class Fighter extends Unit implements Fightable{
public void move(int x, int y) {/*내부 구현*/}
public void attack(Unint U) {/*내부 구현*/}
}
메서드 중 일부만 구현한다면, abstract를 붙여 추상클래스로 선언해야 한다.
인터페이스의 모든 메서드는 public 이고, 오버라이딩할 때 부모 메서드보다 넓은 범위의 접근 제어자를 사용해야 하므로 구현하는 클래스의 접근 제어자는 반드시 public으로 해야 한다.
인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
인터페이스도 클래스처럼 참조 변수를 이용해 사용 가능하다.
Fightable myFighter = new Fighter();
위와 같이 선언해서 사용할 경우 Fightable 인터페이스에서 선언한 메서드 또는 멤버 변수만 사용 가능하고 Fighter 클래스에서만 선언한 메서드 또는 멤버 변수는 사용할 수 없다.
이는 캐스팅을 통해 사용할 수 있다.
interface Fightable{
public void move(int x, int y)
public void attack(Unit U)
}
class Fighter implements Fightable{
public void move(int x, int y) { /*내부 구현*/}
public void attack(Unit U) {/*내부 구현*/}
public int fightCnt;
public void setFightCnt(int n){
this.fightCnt = n;
}
}
public static void main(String[] args){
Fightable myFighter = new Fighter();
myFighter.move(3, 5); //가능
myFighter.setFightCnt(5); // 불가능
(Fighter)myFighter.setFightCnt(5); //가능
}
인터페이스 상속
- 인터페이스는 인터페이스로부터만 상속받을 수 있다.
- 다중 상속이 가능하다.
- 클래스와 달리 Object클래스 같은 최상위 부모 클래스가 없다.
interface Movable {
void move(int x, int y);
}
interface Attackable {
void attack(Unit u);
}
// Movable과 Attackable을 상속받은 Fightable 인스턴스
interface Fightable extends Movable, Attackable {}
인터페이스의 기본 메소드 (Default Method), 자바 8
인터페이스에 추상 메서드만 선언할 수 있었지만, 자바 8부터 디폴트 메서드를 추가할 수 있다.
디폴트 메서드란 추상 메서드의 기본적인 구현을 제공하는 메서드로, 추상 메서드가 아니기 때문에 디폴트 메서드가 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
메서드 앞에 키워드 default를 붙이며 일반 메서드처럼 몸통{}이 있어야 한다. 접근제어자는 public이며 생략 가능하다.
interface MyInterface {
void method(); // 추상메서드
default void neMethod() {} // 디폴트 메서드
}
디폴트 메서드가 기존의 메서드와 이름이 중복되는 경우 | |
여러 인터페이스의 디폴트 메서드 간의 충돌 | 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩 한다. |
디폴트 메서드와 부모클래스의 메서드 간의 충돌 | 부모 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다. |
인터페이스의 static 메소드, 자바 8
디폴트 메서드와 마찬가지로 자바 8부터 추가할 수 있다.
static이므로 구현한 클래스에서 재정의할 수 없으며 반드시 인터페이스명.메서드 형식으로 호출해야 한다.
인터페이스에 static 메서드를 선언함으로써, 인터페이스를 이용하여 간단한 기능을 가지는 유틸리티 성 인터페이스를 만들 수 있게 되었다.
public interface Calculator {
public int plus(int i, int j);
public int multiple(int i, int j);
default int exec(int i, int j){
return i + j;
}
public static int exec2(int i, int j){ //static 메소드
return i * j;
}
}
//인터페이스에서 정의한 static메소드는 반드시 인터페이스명.메소드 형식으로 호출해야한다.
public class MyCalculatorExam {
public static void main(String[] args){
Calculator cal = new MyCalculator();
int value = cal.exec(5, 10);
System.out.println(value);
int value2 = Calculator.exec2(5, 10); //static메소드 호출
System.out.println(value2);
}
}
인터페이스의 private 메소드, 자바 9
자바 8부터 default 메서드와 static 메서드를 사용할 수 있게 되면서 인터페이스 내에서 구현이 가능해졌다.
앞선 과제에서 외부에 드러날 필요가 없는 메서드들은 private 제어자를 이용해 캡슐화를 할 수 있다고 했다.
자바 8에서는 인터페이스 내 구현만 가능하고 private 사용은 불가해 캡슐화가 불가했지만 자바 9부터는 private 사용이 가능해졌다.
Reference)
자바의 정석 - 남궁 성
programmers.co.kr/learn/courses/5
'IT > JAVA' 카테고리의 다른 글
자바 멀티쓰레드 프로그래밍 - 백기선님 스터디 10주차 과제 (0) | 2021.03.29 |
---|---|
자바 예외처리 - 백기선님 스터디 9주차 과제 (0) | 2021.03.16 |
자바 패키지 - 백기선님 스터디 7주차 과제 (0) | 2021.02.26 |
자바 상속 - 백기선님 스터디 6주차 과제 (0) | 2021.02.19 |
자바 클래스 - 백기선님 스터디 5주차 과제 (0) | 2021.02.13 |