🥊 이 글은 제대로 파는 자바 - Java 끝.장.내.기 (얄팍한 코딩사전) 강의 내용을 정리한 글입니다.
// 이전 글에 이어지는 예제 (Button)
public class Main {
public static void main(String[] args) {
// 가능 - 자식 클래스는 부모 클래스에 속함
Button button1 = new Button("Enter");
Button button2 = new ShutDownButton();
Button button3 = new ToggleButton("CapsLock", true);
// 불가 - 부모는 자식 클래스에 속하지 않음
ShutDownButton button4 = new Button("Enter"); // error!
// 불가 - 서로 다른 자식끼리는 포함 관계가 아님
ToggleButton button5 = new ShutDownButton(); // error!
}
}
// 편의: 모두 Button이란 범주로 묶어 배열 등에서 사용 가능
Button[] buttons = {
new Button("Space"),
new ToggleButton("NumLock", false),
new ShutDownButton()
};
for (Button button : buttons) {
bitton.onClick(); // 모든 버튼들은 onClick 메소드를 가짐
}
public class Main {
public static void main(String[] args) {
YalcoChicken[] ycStores = {
new YalcoChicken(3, "판교"),
new YalcoChicken(17, "강남"),
new YalcoChickenDT(108, "철원"),
};
for (YalcoChicken store : ycStores) {
if (store instanceof YalcoChickenDT) {
// 자식 클래스의 기능을 사용하려면 명시적 타입 변환
((YalcoChickenDT) store).takeDTOrder();
} else {
store.takeHallOrder();
}
}
}
}
final
final
필드final
메소드final
인스턴스final
클래스abstract
클래스YalcoGroup
에서 매장을 낼 수는 없음YalcoChicken
과 YalcoCafe
의 매장은 YalcoGroup
소속abstract
메소드static
)는 인스턴스를 생성해서 쓰는 것이 아니므로 추상 메소드로 작성할 수 없음// YalcoGroup.java
public abstract class YalcoGroup {
protected static final String CREED = "우리의 %s 얄팍하다";
// 클래스 메소드는 abstract 불가
abstract static String getCreed (); // error!
protected final int no;
protected final String name;
public YalcoGroup(int no, String name){
this.no = no;
this.name = name;
}
public String intro() {
return "%d호 %s점입니다.".formatted(no, name);
}
abstract void takeOrder();
// public abstract void takeOrder(); // 접근제어자 의미 없음
}
// YalcoChicken.java
public class YalcoChicken extends YalcoGroup {
public static String getCreed() {
return CREED.formatted("튀김옷은");
}
protected static int lastNo = 0;
public YalcoChicken(String name) {
super(++lastNo, name);
}
// 추상 메소드는 반드시 구현해야 함!
@Override
public void takeOrder() {
System.out.printf("얄코치킨 %s 치킨을 주문해주세요.%n");
}
}
// YalcoCafe.java
public class YalcoCafe extends YalcoGroup {
public static String getCreed() {
return CREED.formatted("원두향은");
}
protected static int lastNo = 0;
private boolean isTakeout;
public YalcoCafe(String name, boolean isTakeout) {
super(++lastNo, name);
this.isTakeout = isTakeout;
}
// 추상 메소드 반드시 구현
@Override
public void takeOrder() {
System.out.printf("얄코카페 %s 음료를 주문해주세요.%n", super.intro());
if (!isTakeout) System.out.println("매장에서 드시겠어요?");
}
}
// Main.java
public class Main {
public static void main(String[] args) {
// 추상 클래스로 인스턴스 생성 불가
YalcoGroup yalcoGroup = new YalcoGroup(1, "서울"); // error!
YalcoChicken chickenStore1 = new YalcoChicken("판교");
YalcoChicken chickenStore2 = new YalcoChicken("강남");
YalcoCafe cafeStore1 = new YalcoCafe("울릉", true);
YalcoCafe cafeStore2 = new YalcoCafe("강릉", false);
YalcoGroup[] ycStores = {
chickenStore1, chickenStore2,
cafeStore1, cafeStore2
};
/*
출력:
얄코치킨 1호 판교점입니다. 치킨을 주문해주세요.
얄코치킨 2호 강남점입니다. 치킨을 주문해주세요.
얄코치킨 1호 울릉점입니다. 음료를 주문해주세요.
얄코치킨 2호 강릉점입니다. 음료를 주문해주세요.
매장에서 드시겠어요?
*/
for (YalcoGroup ycStore : ycStores) {
ycStore.takeOrder();
}
System.out.println(YalcoChicken.getCreed()); // 출력: 우리의 튀김옷은 얄팍하다
System.out.println(YalcoCafe.getCreed()); // 출력: 우리의 원두향은 얄팍하다
}
}
추상 클래스 | 인터페이스 |
---|---|
extends | implements |
다중 적용 불가 | 다중 적용 가능 |
상속관계에 의한 제한 있음 | 상속관계에 의한 제한 없음 |
생성자 있음 | 생성자 없음 |
구상 메소드, 추상 메소드 모두 가능 | 추상 메소드(abstract 안 붙여도 됨), default 구상 메소드, 클래스 메소드 |
필드 모두 가능 | 상수 필드만 가능 (final 명시 불필요) |
public static final
(명시할 필요 X)public abstract
(명시할 필요 X)default
구상 메소드
default
로 구상 메소드를 넣을 수 있도록 한 이유
- 사용되던 인터페이스에 새로운 기능을 추가해야 한다면?
- 새로운 자바 버전의 라이브러리 인터페이스에 새 기능이 추가되어야 한다면 그 인터페이스가 적용된 클래스들에 전부 다 구상 메소드를 새로 추가해줘야 할 것임...
- 해당 인터페이스의 하위 클래스들을 일일이 수정하지 않아도 되도록, 즉 하위 호환성을 위해!
// FoodSafety.java
public interface FoodSafety {
// 클래스 메소드
static void announcement() {
System.out.println("식품안전 관련 공지");
}
// default 구상 메소드
default void regularInspection() {
System.out.println("정기 체크");
}
// 추상 메소드 (abstract 명시 X)
void cleanKitchen();
void employeeEducation();
}
// YalcoChicken.java
public class YalcoChicken implements FoodSafety {
// 인터페이스의 추상 메소드를 구현한 구상 메소드 필수!
@Override
public void cleanKitchen() {
System.out.println("매일 주방 청소");
}
@Override
public void employeeEducation() {
System.out.println("직원 위생 교육");
}
}
// Main.java
public class Main {
public static void main(String[] args) {
FoodSafety.announcement(); // 식품안전 관련 공지
YalcoChicken store = new YalcoChicken();
store.regularInspection(); // 정기 체크
store.cleanKitchen(); // 매일 주방 청소
store.employeeEducation(); // 직원 위생 교육
}
}