[public] interface 인터페이스명 {
// 상수 (public static final)
타입 상수명 = 값;
// 추상 메소드 (public abstract)
타입 메소드명(매개변수, ...);
// 디폴트 메소드 (자바8부터 New)
default 타입 메소드명(매개변수, ...){...} // 구현 클래스가 재정의 하지 않아도
실행될 코드
// 정적 메소드 (자바8부터 New)
static 타입 메소드명(매개변수, ...){...}
}
public class 구현클래스명 implements 인터페이스명 {
// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
// 안에 자체적으로 필요한 메소드를 만들수도 O
}
인터페이스 변수 = new 인터페이스() {
// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
}
public class 구현클래스명 implements 인터페이스A, 인터페이스B {
// 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
// 인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
}
인터페이스 변수;
변수 = 구현객체;
ex. RemoteControl rc;
rc = new Television();
rc = new Audio();
public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2 {...}
추상클래스 | 인터페이스 | |
---|---|---|
사용 | extends 클래스명 | implements 인터페이스명 |
상속과 구현 | 단일상속O 다중상속X | 단일구현 O 다중구현 X 다중상속 O |
필드변수 | 자식이 사용가능한 값, instance멤버 변수 | 상수 - static final로 인식 |
메소드 | 몸통 구현, 선언 | 선언부 (추상메소드로 인식) |
다형성 | 자식 클래스 객체 저장 가능 | 구현 클래스 객체 저장 가능 |
개념 | is a | has a |
인터페이스 변수 = 구현객체
구현클래스 변수 = (구현클래스) 인터페이스변수;
: 구현 객체가 인터페이스 타입으로 자동변환하면, 인터페이스에 선언된 메소드만 사용 가능..
: instanceof를 통해 구현객체가 인터페이스 타입으로 변환되었는지 확인 후에 사용
ex.
인터페이스 ABCD가 있음
C는 A와 B를 상속받고, D는 그런 C를 상속받음
각 인터페이스에 있는 메서드를 aa, bb, cc ,dd라고 가정
interface A {
void aa();
}
interface B {
void bb();
}
interface C extends A, B {
void cc();
}
interface D extends C {
void dd();
}
클래스 Sample은 인터페이스 D를 통해서 만든 구현 클래스
클래스 Sample안에 있는 메서드를 ss라고 가정
class Sample implements D {
void ss() {
System.out.println("ss");
}
@Override
public void aa() {
}
@Override
public void bb() {
}
@Override
public void cc() {
}
@Override
public void dd() {
}
}
메소드에 접근가능한지에 대한 비교
public class SampleMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Sample s = new Sample(); // 구현 클래스 생성
A a = s; // 부모
B b = s; // 부모
C c = s; // 부모
D d = s; // 내가 구현한 D타입
// 몸통은 Sample
// O => 상위 인터페이스가 가진 메소드 접근 가능
a.aa();
b.bb();
c.cc();
// O => c는 a,b를 상속 받았기 때문에 가능
c.aa();
// X => b랑 a는 연결된 관계가 아님 (서로한테 뭐있는지 몰라..)
b.aa();
// O => d는 a,b,c를 상속받아서 만들어졌기 때문에 접근가능
d.aa();
d.dd();
d.bb();
// X => sample이 D를 구현 (d는 자신의 구현 클래스 안에 있는 ss라는 메소드의 존재를 모름)
d.ss();
// X => ss는 클래스 자체의 메소드 (d는 어떤 클래스가 자신을 구현해서 그 안에 어떤 메소드를 만들었는지 알 수 없음)
s.ss();
// d로 구현을 한 Sample 타입으로 d를 강제 타입 변환을 해서 d한테
// sample 이라는 현 클래스가 있다는 걸 인지를 시켜주면
// ss라는 메서드에 접근할 수 있음
Sample temp = (Sample)d;
temp.ss(); // => O
}
}