코딩 기록들
객체지향 프로그래밍 16. 여러 인터페이스구현 & 인터페이스 상속 본문
여러 인터페이스 구현
- 자바의 인터페이스는 구현 코드가 없으므로 (자바8이후로 default, static메소드가 추가되긴 했지만 기본적으로는 구현코드 없음) 하나의 클래스가 여러 인터페이스는 구현 할 수 있음 (여러 implement 가능! (기존자바는 diamond problem때문에 다중상속이 안됨. 단일상속만 가능함))
- 디폴트 메서드가 중복 되는 경우는 구현 하는 클래스에서 재정의 하여야 함 (모호하므로)
- 여러 인터페이스를 구현한 클래스는 인터페이스 타입으로 형 변환 되는 경우 해당 인터페이스에 선언된 메서드만 사용 가능 함
public interface Buy {
void buy(); //단일타입
default void order(){
System.out.println("buy order");
}
}
public interface Sell {
void sell();
default void order() {
System.out.println("sell order");
}
}
//2개의 인터페이스 상속
public class Customer implements Buy, Sell{
@Override
public void sell() {
System.out.println("customer sell");
}
@Override
public void buy() {
System.out.println("customer buy");
}
@Override
public void order() {
//default 매소드 재정의
// Buy.super.order();
//윗줄아님 아랫줄 둘중하나로 재정의 하기
System.out.println("customer order");
}
public void hello(){
System.out.println("hello");
}
}
public class CustomerTest {
public static void main(String[] args) {
// customer로 참조하는것은 다 쓸 수 있음
Customer customer = new Customer();
customer.buy();
customer.sell();
customer.order();
customer.hello();
//업캐스팅 : 타입내포 + 상위클래스로의 타입으로 자동 형변환
Buy buyer = customer;
// buyer로 참조하는것은 buy에 선언된 2가지만 가능
buyer.buy(); //buy order
buyer.order(); //customer order
Sell seller = customer;
// seller로 참조하는것은 sell에 선언된 2가지만 가능
seller.sell(); // customer sell
seller.order(); //customer order -> Customer로 재정의했기때문에 virtual method에 의해 나오는 결과
}
}
인터페이스의 상속
- 인터페이스 사이에도 상속을 사용할 수 있음
- extends 키워드를 사용 - extends 키워드 뒤 여러개(ex. X, Y)는 인터페이스간의 상속임
- 인터페이스는 다중 상속이 가능하고 구현 코드의 상속이 아니므로 타입 상속 이라고 함
public interface X {
void x();
}
public interface Y {
void y();
}
// MyInterface 가 X, Y 2개의 상속(extends)을 받는다
public interface MyInterface extends X, Y{ //extends 키워드 뒤에 여러개(X, Y)는 인터페이스간의 상속임
// X, Y 메소드 2개를 모두 선언하는것
void myMethod();
}
public class MyClass implements MyInterface{
// MyInterface를 상속받으면 아래의 3개 메소드 모든 메소드 구현해야됨
@Override
public void x() {
System.out.println("x()");
}
@Override
public void y() {
System.out.println("y()");
}
@Override
public void myMethod() {
System.out.println("myMethod()");
}
}
public class MyClassTest {
public static void main(String[] args) {
MyClass mClass = new MyClass();
//X로 선언되면 x만 사용할수있음
X xClass = mClass;
xClass.x();
//y로 선언되면 y만 사용할수있음
Y yClass = mClass;
yClass.y();
// 실제로 !모두! 쓸려면 MyClass타입으로 써야됨!!
MyClass iClass = mClass;
iClass.x();
iClass.y();
iClass.myMethod();
}
}
클래스 상속과 인터페이스 구현 함께 쓰기
책이 순서대로 대여가 되는 도서관 구현
- 책을 보관하는 자료 구조가 Shelf에 구현됨 - ArrayList
- Queue 인터페이스 구현
- Shelf 클래스를 상속 받고 Queue 구현
//순서대로 물건을 담아놓기위해 : ArrayList 사용
import java.util.ArrayList;
public class Shelf {
//상속 받을수있도록 protected로 선언 (외부 클래스는 접근 할 수 없지만, 하위 클래스는 접근 할 수 있음)
protected ArrayList<String> shelf;
public Shelf(){ //생성자 호출할때 멤버변수 초기화하기!
shelf = new ArrayList<String>();
}
public ArrayList<String> getShelf(){
return shelf;
}
public int getCount(){ // 남아있는 물건개수 반환해주는 count
return shelf.size();
}
}
public interface Queue {
//책의 이름을 가지고 들어감 enQueue : 매개변수 title 필요
// 꺼낼땐 deQueue로 책이름 반환
void enQueue(String title);
String deQueue();
//큐가 몇개있는지 사이즈 알려줌
int getSize();
}
public class BookShelf extends Shelf implements Queue {
@Override
public void enQueue(String title) {
shelf.add(title);
}
@Override
public String deQueue() {
return shelf.remove(0);
}
@Override
public int getSize() {
return getCount();
}
}
public class BookShelfTest {
public static void main(String[] args) {
Queue bookQueue = new BookShelf();
bookQueue.enQueue("가");
bookQueue.enQueue("나");
bookQueue.enQueue("다");
bookQueue.enQueue("라");
bookQueue.enQueue("마");
System.out.println(bookQueue.getSize()); //5
//deQueue부를때마다 먼저 들어간 순서대로 한권씩 제거가 됨
System.out.println(bookQueue.deQueue()); //가
System.out.println(bookQueue.deQueue()); //나
System.out.println(bookQueue.deQueue()); //다
System.out.println(bookQueue.deQueue()); //라
System.out.println(bookQueue.deQueue()); //마
}
}