인터페이스(interface)
추상 메서드의 집합
구현된 것이 전혀 없는 설계도. 모든 멤버가 public
cf) 추상 클래스와 인터페이스 비교
=> 추상 클래스는 일반 클래스에 추상 메서드를 가지고 있음, 인터페이스는 추상 메서드만 가지고 있음
interface 인터페이스이름{
public staic final 타입 상수이름 = 값; //상수. 변수를 가질 수 없음
public abstract 메서드이름(매개변수목록); //추상메서드
}
package chapter07;
interface PlayingCardS18E1{
//상수
public static final int SPADE = 4;
final int DIAMOND = 3; //== (public static final) int DIAMOND = 3;
static int HEART = 2; //== (public static final) int HEART = 2;
int CLOVER = 1; //== (public static final) int CLOVER = 1;
//추상 메서드
public abstract String getCardNumber();
String getCardKind(); //== (public abstract) String getCardKind();
}
public class Study18Ex1 {
}
인터페이스의 상속
인터페이스의 조상은 인터페이스만 가능(Object가 최고 조상이 아님)
다중 상속(조상이 여러 개)이 가능(추상 메서드는 충돌해도 문제 없음)
ㄴ선언부가 다르면 둘 다 상속받으면 됨, 선언부가 같고 구현부가 다르면 어느쪽을 상속받을지 결정할 수 없음
package chapter07;
interface FightableS18E2 extends MovableS18E2, AttackableS18E2{}
interface MovableS18E2{
void move(int x, int y);
}
interface AttcakableS18E2{
void attack(Unit u);
}
public class Study18Ex2 {
}
//인터페이스(미완성 설계도 => 완성)의 구현
//인터페이스에 정의된 추상 메서드를 완성하는 것
//추상클래스 완성과 동일(implements 키워드만 사용한다는 점과 차이)
//class 클래스이름 implements 인터페이승름{
// 인터페이스에 정의된 추상메서드를 모두 구현해야함
//}
//일부만 구현하는 경우, 클래스 앞에 abstract를 붙여야 함
//※구현 => 미완성을 완성된 설계도로 만드는 것. 구현부를 만드는 것
//추상 클래스와 인터페이스의 차이? => 인터페이스는 iv를 가질 수 없음
인터페이스를 이용한 다형성(조상참조변수로 자식객체)
인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능
인터페이스를 메서드의 리턴타입으로 지정할 수 있음
package chapter07;
abstract class UnitS19E1{
int x, y;
abstract void move(int x, int y);
void stop() {
System.out.println("정지");
}
}
interface FightableS19E1{
//인터페이스의 모든 메서드는 public abstract. 예외없이
void move(int x, int y); //public abstract가 생략됨
void attack(FightableS19E1 f); //public abstract가 생략됨
}
class FighterS19E1 extends UnitS19E1 implements FightableS19E1{
//오버라이딩 규칙 : 조상보다 접근제어가자 좁으면 안됨
public void move(int x, int y) {
System.out.println(x + ", " + y + " 로 이동");
}
public void attack(FightableS19E1 f) {
System.out.println(f+" 를 공격");
}
}
public class Study19Ex1 {
public static void main(String[] args) {
FighterS19E1 f = new FighterS19E1(); //가능
f.move(100, 200);
f.attack(f);
f.stop();
System.out.println();
UnitS19E1 u = new FighterS19E1();
u.move(100, 200);
// u.attack(u); Unit에는 attack() 메서드가 없어 호출 불가
u.stop();
FightableS19E1 fa = new FighterS19E1();
fa.move(100, 200);
fa.attack(fa);
// fa.stop(); Fightable에 stop() 메서드가 없어 호출 불가
}
}
인터페이스의 장점
두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 '중간 역할'
선언(설계)와 구현을 분리시킬 수 있게 함
package chapter07;
class A {
public void method(B b) {
b.method();
}
}
class B{
public void method() {
System.out.println("B클래스 method()");
}
}
public class Study20Ex1 {
public static void main(String[] args) {
A a = new A();
a.method(new B()); //A가 B를 사용(의존)
}
}
위의 코드에서 C클래스를 만들어서 C클래스의 메소드를 사용
package chapter07;
class A {
public void method(C b) {
b.method();
}
}
class B{
public void method() {
System.out.println("B클래스 method()");
}
}
class C{
public void method() {
System.out.println("C클래스 method()");
}
}
public class Study20Ex1 {
public static void main(String[] args) {
A a = new A();
a.method(new C()); //A가 C를 사용(의존)
}
}
A가 B 대신 C를 사용하려면 두 곳을 수정해야함
바꾸지 않기 위해서 인터페이스 구현
package chapter07;
class A {
public void method(I i) {
i.method();
}
}
//B 클래스의 선언과 구현을 분리
interface I{
public void method(); //method()의 선언
}
class B implements I{
public void method(){
System.out.println("B클래스 method()"); //method()의 구현
}
}
class C{
public void method() {
System.out.println("C클래스 method()");
}
}
public class Study20Ex1 {
public static void main(String[] args) {
A a = new A();
a.method(new B());
}
}
C method()를 사용하기위해서는 똑같이 C 클래스에 I를 구현
package chapter07;
class A {
public void method(I i) { //인터페이스 I를 구현한 것만
i.method();
}
}
//B 클래스의 선언과 구현을 분리
interface I{
public void method(); //method()의 선언
}
class B implements I{
public void method(){
System.out.println("B클래스 method()"); //method()의 구현
}
}
class C implements I{
public void method() {
System.out.println("C클래스 method()");
}
}
public class Study20Ex1 {
public static void main(String[] args) {
A a = new A();
a.method(new B());
a.method(new C()); //A가 C를 사용(의존)
}
}
개발 시간을 단축
변경에 유리한 유연한 설계가 가능
표준화가 가능(ex, JDBC)
서로 관계없는 클래스들을 관계를 맺을 수 있음
디폴트 메서드, static 메서드
JDK 1.8부터 인터페이스에 디폴트 메서드, static 메서드 추가 가능
인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어려움 => 디폴트 메서드
디폴트 메서드는 인스턴스 메서드(인터페이스 원칙 위반) => 예외
디폴트 메서드가 기존의 메서드와 충돌할 때의 해결책 => 직접 오버라이딩하면 해결