이번 편의 목표: interface를 정의하고 implements로 구현합니다. extends와 implements가 한 클래스에 함께 있을 수 있다는 점도 확인합니다.
상속은 '~의 한 종류'에 맞습니다. 전자책은 책의 한 종류입니다. 예약 가능은 종류가 아니라 역할입니다. 종이책도 전자책도 예약할 수 있고, 어떤 잡지는 예약하지 않을 수 있습니다. 역할을 부모 클래스로 억지로 올리면 부모가 두 개 필요해지는데, 자바 클래스는 extends를 하나만 할 수 있습니다.
인터페이스는 구현 없이 역할을 선언합니다. 클래스는 implements로 그 역할을 수행한다고 밝히고 메서드 본문을 제공합니다.
인터페이스 정의와 구현
public interface Reservable {
boolean canReserve();
}인터페이스의 메서드는 구현 클래스에서 public으로 구현합니다. 필드로 상태를 쌓는 곳이 아니라, 클래스가 어떤 동작을 약속하는지를 적는 곳입니다.
12편과 13편의 EBook이 Book을 상속한 상태에서 예약 역할을 추가하면 선언은 다음처럼 바뀝니다.
public class EBook extends Book implements Reservable {
private final String fileName;
public EBook(String title, int lateDays, String fileName) {
super(title, lateDays);
if (fileName == null || fileName.isBlank()) {
throw new IllegalArgumentException("파일 이름이 필요합니다.");
}
this.fileName = fileName.trim();
}
public String getFileName() {
return fileName;
}
@Override
public int lateFee() {
return getLateDays() * 50;
}
@Override
public boolean canReserve() {
return true;
}
}extends는 앞에 한 번, implements는 그 뒤에 옵니다. 상속으로 받은 연체료 재정의와 인터페이스 구현이 한 클래스에 같이 있습니다.
EBook ebook = new EBook("파이썬 기초", 2, "python.epub");
System.out.println(ebook.lateFee());
System.out.println(ebook.canReserve());출력은 100과 true입니다.
여러 인터페이스
클래스가 구현할 인터페이스는 여러 개일 수 있습니다. 쉼표로 구분합니다.
public interface Downloadable {
String downloadName();
}전자책이 예약도 되고 파일 내려받기도 된다면 implements Reservable, Downloadable 처럼 적습니다. 각 인터페이스의 메서드를 모두 구현해야 구체 클래스가 됩니다. 하나라도 빠지면 그 클래스는 abstract가 되어야 합니다.
예약만 다루는 코드는 부모 클래스 대신 인터페이스 타입으로 받을 수 있습니다.
Reservable item = new EBook("자바 입문", 1, "java.epub");
System.out.println(item.canReserve());이 변수로는 canReserve만 바로 호출할 수 있습니다. lateFee는 Reservable의 약속이 아니기 때문입니다. 역할에 필요한 메서드만 보이게 나누는 것이 인터페이스의 목적입니다.
abstract 클래스와 인터페이스는 둘 다 인스턴스를 직접 만들 수 없습니다. 차이는 사용 목적입니다. abstract 클래스는 필드와 생성자처럼 공통 자료를 가진 부모에 맞습니다. interface는 자료의 종류와 상관없이 구현해야 하는 역할에 맞습니다.
직접 해 보기
Reservable을 구현하는 클래스를 만들고 canReserve가 false를 반환하게 하세요. 참고 도서는 예약하지 않는 경우입니다.
해설
public class ReferenceBook extends Book implements Reservable {
public ReferenceBook(String title) {
super(title, 0);
}
@Override
public boolean canReserve() {
return false;
}
}ReferenceBook book = new ReferenceBook("사전"); 을 만든 뒤 book.canReserve()는 false이고, book.lateFee()는 0입니다. 연체 일수를 0으로 넘겼기 때문입니다.
여기까지 오면 자료형, 조건, 반복, 메서드, 클래스, extends, abstract, implements가 한 예제 안에서 역할을 나눕니다. 다음 실습은 자신의 업무에서 종류와 역할을 찾아, 종류는 상속이나 추상 클래스로, 역할은 인터페이스로 옮겨 보는 일입니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.