인터페이스에 선언되는 메소드와 변수
interface Printable {
public void print(String doc); // 추상 메소드 - 생략해도 무조건 public
}
interface Printable {
public static final int PAPER_WIDTH = 70; // 인스턴스 생성 안되서 원래 변수 선언이 안됨! - 생략해도 무조건 public static final
public static final int PAPER_HEIGHT = 120;
public void print( String doc );
}
인터페이스간 상속 : 문제 상황의 제시
MS
interface Printable {
void print( String doc );
void printCMYK ( String doc );
}
컬러 출력 위한 메소드 추가되면? 시스템 전체에 문제 발생
삼성 프린터
class SPrinterDriver implements Printable {
@Override
public void print(String doc) { ... }
// 이 클래스에서 printCMYK 메소드 구현해야 함
}
LG 프린터
class LPrinterDriver implements Printable {
@Override
public void print(String doc) { ... }
// 이 클래스에서 printCMYK 메소드 구현해야 함
}
인터페이스를 구현하는 클래스는 해당 인터페이스의 모든 추상 메소드를 구현해야 한다. 그래야 인스턴스 생성 가능!!!
제시한 문제의 해결책 : 인터페이스의 상속
interface Printable {
void print(String doc);
}
인터페이스간 상속도 extends로 표현
interface ColorPrintable extends Printable {
void printCMYK(String doc);
}
class SPrinterDriver implements Printable {
... // 기존 클래스 수정할 필요 없음
}
컬러 프린터 드라이버
class Prn909Drv implements ColorPrintable {
@Override
public void print (String doc) {
// 흑백 출력
}
@Override
public void printCMYK(String doc) {
// 컬러 출력
}
}
인터페이스의 디폴트 메소드 : 문제 상황의 제시
총 256개의 인터페이스가 존재하는 상황에서 모든 인터페이스에 다음 추상 메소드를 추가해야 한다면?
void printCMYK(String doc);
인터페이스간 상속?
- 물론 인터페이스간 상속으로 문제 해결 가능하다. 다만 인터페이스의 수가 256개 늘어날 뿐이다.
문제 상황의 해결책 : 인터페이스의 디폴트 메소드
총 256개의 인터페이스가 존재하는 상황에서 모든 인터페이스에 다음 추상 메소드를 추가해야 한다면?
void printCMYK(String doc);
다음 디폴트 메소드로 이 문제를 해결하면 인터페이스의 수가 늘어나지 않는다.
default void printCMYK(String doc) { } // 디폴트 메소드
- 구현을 꼭 하지 않아도 된다! 메소드 몸체가 있기때문에 필수사항은 아님! 단, 256개에 다 넣어줘야함!
디폴트 메소드의 효과
interface Printable {
void print(String doc);
}
인터페이스 교체
interface Printable {
void print(String doc);
default void printCMYK(String doc) { }
}
class SPrinterDriver implements Printable {
@Override
public void print(String doc) { ... }
}
기존의 정의된 클래스 :
인터페이스 교체로 인해 코드 수정 필요 없다.
class Prn909Drv implements Printable {
@Override
public void print( String doc ) { ... }
@Override
public void printCMYK ( String doc ) { ... }
}
새로 정의된 클래스
인터페이스의 static 메소드
"인터페이스에도 static 메소드를 정의할 수 있다"
"그리고 인터페이스의 static 메소드 호출 방법은 클래스의 static 메소드 호출 방법과 같다"
interface Printable {
static void printLine ( String str ) {
System.out.println (str);
}
default void print ( String doc ) {
printLine (doc); // 인터페이스의 static 메소드 호출
}
}
인터페이스 대상의 instanceof 연산
if ( ca instanceof Cake ) ...
Cake는 클래스의 이름도, 인터페이스의 이름도 될 수 있다.
ca가 참조하는 인스턴스를 Cake형 참조변수로 참조할 수 있으면 true 반환!
- ca가 참조하는 인스턴스가 Cake를 직접 혹은 간접적으로 구현한 클래스의 인스턴스인 경우 true 반환!
인터페이스 대상의 instanceof 연산의 예
interface Printable {
void printLine ( String str );
}
class SimplePrinter implements Printable {
public void printLine ( String str ) {
System.out.println( str );
}
}
class MultiPrinter extends SimplePrinter {
public void printLine ( String str ) {
super.printLine("start of multi...");
super.printLine(str);
super.printLine("end of multi");
}
}
public static void main(String[] args) {
Printable prn1 = new SimplePrinter();
Printable prn2 = new MultiPrinter();
if (prn1 instanceof Printable) // true
prn1.printLine("This is a simple printer.");
System.out.println();
if(prn2 instanceof Printable) // ture
prn2.printLine("This is a multhful printer.");
}
인터페이스 대상의 instanceof 연산의 예
interface Upper { } // 마커 인터페이스
interface Lower { } // 마커 인터페이스
interface Printable {
String getContents();
}
class Report implements Printable, Upper {
String cons;
Report(String cons) {
this.cons = cons;
}
public String getContents() {
return cons;
}
}
public void printContents ( Printable doc ) {
if ( doc instanceof Upper ) {
System.out.println((doc.getContents()).toUpperCase());
}
else if ( doc instanceof Lower ) {
System.out.println((doc.getContents()).toLowerCase());
}
else
System.out.println(doc.getContents());
}
클래스에 특정 표시를 해 두기 위한 목적으로 정의된 인터페이스를 마커 인터페이스라 한다. 마커 인터페이스에는 구현해야 할 메소드가 없는 경우가 흔하다.
추상 클래스
public abstract class House { // 추상 클래스
public void methodOne() {
System.out.println("method one");
}
public abstract void methodTwo(); // 추상 메소드
}
하나 이상의 추상 메소드를 지니는 클래스를 가리켜 추상 클래스라 한다.
그리고 추상 클래스를 대상으로는 인스턴스 생성이 불가능하다. 물론 참조변수 선언은 가능하다.
(단, 인터페이스와는 달리 인스턴스 변수와 인스턴스 메소드 정의 가능!!)
'# 02 > Java' 카테고리의 다른 글
[윤성우의 열혈자바] 2-4. 자바의 기본 자료형 (0) | 2019.10.18 |
---|---|
[윤성우의 열혈자바] 1-2. 자바 프로그램과 실행의 원리에 대한 이해 (0) | 2019.10.18 |
[Java] 인터페이스의 기본과 그 의미 (0) | 2019.08.19 |
[Java] 싱글턴 패턴 (0) | 2019.07.17 |
[Java] 제네릭 2 (0) | 2019.07.09 |