0. 인터페이스(Interface)
추상(abstract) 메서드는 하위 클래스에서 오버라이딩하도록 기대되는 메서드이다.
이때, 구체적인 로직을 가지고 있는 메서드나, 변수일 수 있다.
하지만 interface는 클래스가 abstract로만 이루어져 있으며 일종의 추상클래스(abstract class)이다.
인터페이스는 본체(구현부)가 없는 추상메서드와 상수(final) 변수만을 멤버로 가질 수 있다.
1. 인터페이스의 작성
interface 인터페이스이름{
public static final 타입 상수이름 = 값; //모든 멤버변수는 public static final이어야 함.
public abstract 메서드이름(매개변수목록); //모든 메서드는 public abstract이어야 함.
}
interface I{
public void z();
}
인터페이스 I를 보면 메서드 z가 있다. 그러나 구현부는 존재하지 않는다.
그래서 이를 구현하는 클래스(A)에서 메서드의 로직을 구현(implements) 해야 한다.
이때, 인터페이스 I에서 단순히 public void z(); 라고 되어있지만 사실 앞에 public abstract가 생략되었다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
- 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
class A implements I{
public void z(){ };
}
인터페이스를 구현하는 클래스(A)에 있는 추상메서드 public void z();를 구현해주어야 한다.
위 예제에서는 따로 로직을 만들어주진 않았다.
<예제 1>
public interface PlayingCard {
public static final int SPADE = 4;
final int DIMAOND = 3; // public static final이 생략됨 (멤버변수)
static int HEART = 2; // public static final이 생략됨 (멤버변수)
int CLOVER = 1; // public static final이 생략됨 (멤버변수)
public abstract String getCardNumber(); // 추상메서드 getCardNumber();
String getCardKing(); // public abstract가 생략된 추상메서드
}
인터페이스는 public으로 선언하는 것이 일반적이다.
<예제 2> 언제 활용하면 좋을까? 변수가 상수(고정된 값)일 경우!
인터페이스 內 변수들은 모두 public static final이라는 점에 착안해서 간단하게 표현이 가능하다!
(※자바 버전 5.0 이후부터 열거형(enum)이 제공되면서 상수 선언이 필요한 일부 상황에서 interface를 대체)
2. 인터페이스의 상속
인터페이스는 인터페이스로부터만 상속받을 수 있으며, 클래스와 달리 다중상속이 가능하다.
interface Movable{
/** 지정된 위치(x,y)로 이동하는 기능의 메서드 */
void move(int x, int y);
}
interface Attackable{
/** 지정된 대상을 공격하는 기능의 메서드 */
void attack(Unit u);
}
interface Fightable extends Movable, Attackable { }
자손인터페이스(Fightable)은 조상 인터페이스(Movable, Attackable)에 정의된 멤버를 상속받으면서
두 개의 추상 메서드 move()와 attack()을 갖는다.
3. 인터페이스의 구현
class 클래스이름 implements 인터페이스이름 {
/** 인터페이스에 정의된 추상메서드를 구현 */
}
class FIghter implements Fightable{
public void move (int x, int y) { /** 내용 생략 */ }
public void attack(Unit u) { /** 내용 생략 */ }
}인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없다.
추상클래스가 상속을 통해 추상메서드를 완성하는 것처럼, 'implements'라는 키워드를 활용한다.
abstract class Fighter implements Fightable{
public void move(int x , int y) { /** 내용 생략 */ }
}
만약 인터페이스 메서드 중 일부만 구현한다면, 추상클래스로 선언되어야 한다.
위 코드에서는 attack을 구현하지 않았으니, Fighter 클래스를 추상클래스로 선언했다.
class Fighter extends Unit implements Fightable{
public void move (int x, int y) { /** 내용 생략 */ }
public void attack (Unit u) { /** 내용 생략 */ }
}
상속과 구현을 동시에 할 수도 있다.
4. 인터페이스를 이용한 다중상속
두 개의 클래스로부터 상속을 받아야 할 상황이라면, 두 조상클래스 중에서 비중이 높은 쪽을 선택하고
다른 한쪽은 클래스 내부에 멤버로 포함시키는 방식으로 처리하거나 or 필요한 부분을 뽑아서 인터페이스로 만든 다음 구현하도록 한다.
5. 인터페이스를 이용한 다형성
1. 자손클래스의 인스턴스를 조상타입의 참조변수로 참조하는 것이 가능하다는 것을 배웠다.
2. 인터페이스는 (구현한) 클래스의 조상이라고 할 수 있다.
3. 인터페이스 타입의 참조변수로 (구현한) 클래스의 인스턴스를 참조할 수 있다.
4. 인터페이스 타입으로의 형변환도 가능하다.
5. 메서드의 매개변수의 타입으로 사용될 수 도 있다.
class Fighter extends Unit implements FIghtable {
public void move(int x, int y) { /* 내용 생략 */ }
public void attack(Fightable f) { /* 내용 생략 */ }
}void attack(Fightable f) { // } // FIghtable 인터페이스를 구현한 클래스의 인스턴스를
// 매개변수로 받는 메서드
Fightable method() { // 인터페이스를 메서드의 리턴타입으로 지정할 수 있다.
return new FIghter();
}
6. 인터페이스의 이해
인터페이스는 두 대상(객체)간의 "연결, 소통"을 돕는 중간 역할을 한다.
또한, 선언과 구현을 분리하게 하는 역할을 하는데, 아래 코드를 통해 알 수 있다.
클래스의 "선언부"와 "구현부"를 분리했다.
1. 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다.
2. 메서드를 사용하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 된다.
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA} Object 클래스 (1) | 2016.08.09 |
---|---|
[JAVA} 예외처리(Exceptpion Handing) (0) | 2016.08.07 |
[JAVA] 추상클래스(Abstract Class) (0) | 2016.08.02 |
[JAVA] 다형성(polymorphism) (3) | 2016.08.02 |
[JAVA] 제어자(modifier) (0) | 2016.08.02 |