- 학습 목표 달성 확인 목록
- [] 추상 클래스를 정의하는 방법과 concrete 클래스와의 차이점을 이해하는가?
abstract class 클래스이름{
...
}
추상클래스의 시그니처이며 아직 클래스를 완성한 상태가 아니라는 뜻이다.
즉 추상메서드를 선언만해주고 이 추상클래스를 상속하는 서브클래스에서 메서드 바디를 완성시킨다.
concrete 클래스는 일반적인 클래스를 말하며 만약 추상 클래스를 상속받으면
그 일반 클래스는 추상메서드를 구현해야한다
- [] 언제 추상 클래스를 사용해야 하는지 아는가?
서브클래스에게 공통 필드나 메서드를 상속해주는 것이 목적이며
이를 통해 여러 클래스를 같은 타입으로 묶어 유지보수하기 쉽다.

- [] 추상 메서드를 정의할 수 있는가?
public abstract class ab {
public abstract void a();
}
class b extends ab {
@Override
public void a() {
System.out.println("추상메서드를 구현하였다!");
}
}
class print {
public static void main(String[] args) {
b bbb = new b();
bbb.a();
}
}
- [] 추상 메서드를 사용해야 하는 상황과 그 의미를 설명할 수 있는가?
서브클래스마다 구현이 다를 수 있는 경우에 사용한다
서브 클래스가 반드시 구현해야 하는 메서드가 있다면 추상 메서드로 선언해야 한다.
추상 메서드를 상속받은 서브 클래스는 반드시 추상 메서드를 구현해야 한다.
만약 서브클래스에서 구현하지않으려면 서브클래스도 추상으로 만들어야 한다
왜냐하면 추상 메서드를 갖는 클래스는 오직 추상 클래스만이 가능하기 때문이다.
- [] 추상 클래스와 추상 메서드를 활용하여 Template Method 패턴을 구현할 수 있는가?
abstract class Letter {
String content;
public void setContent(String content) {
this.content = content;
}
public void print() {
this.printHeader();
System.out.println(this.content);
System.out.println();
System.out.printf(" From %s\n", this.getSign());
System.out.println();
this.printFooter();
}
public abstract void printHeader();
public abstract void printFooter();
public abstract String getSign();
}
class LuckyLetter extends Letter {
@Override
public void printHeader() {
System.out.println("-----------[행원의 편지]-----------");
}
@Override
public String getSign() {
return "영국의 작가로 부터...";
}
@Override
public void printFooter() {
System.out.println("LuckyLuckyLuckyLuckyLuckyLuckyLucky");
}
public static void main(String[] args) {
Letter letter = new LuckyLetter();
LuckyLetter luckyLetter = new LuckyLetter();
letter.setContent("다른사람에게 전달하지않으면," + "악운이 올것 입니다.");
letter.print();
}
}
//결과
-----------[행원의 편지]-----------
다른사람에게 전달하지않으면,악운이 올것 입니다.
From 영국의 작가로 부터...
LuckyLuckyLuckyLuckyLuckyLuckyLucky

수퍼클래스에서 기본적인 흐름만 결정하고 서브클래스에게 세부 구현의 책임을 미뤘다.
이것을 바로 template method라고 부른다.
- [] Math.random() 메서드의 사용법을 아는가?
double rr = (Math.random() * 200);//해당 메서드는 실수라서 실수형으로 리터럴을 받는다
int r = (int) (Math.random() * 200);//int형으로 리터럴을 받으려면 type casting(형변환)을 한다
- [] 인터페이스를 정의하는 방법과 구현하는 방법을 아는가?
인터페이스 클래스를 정의하는 시그니처이다.
(public)(abstract) interface 클래스이름{
public void play();
}
//인터페이스 클래스의 구현체 클래스 생성시
public class 클래스이름 implements 인터페이스클래스이름{
@Override
public void play(){
//클래스 내용을 구현한다.
}
}
-인터페이스 사용 전
%[https://gist.github.com/osk2090/00a0c039403593bfc61f3378abbbb48f]
-인터페이스 사용 후
%[https://gist.github.com/osk2090/7d855a4ea4cf6bfe29ab9ed418a83188]
- [] 인터페이스 문법을 언제 사용해야 하는지 아는가?
같은 역할을 하는 메서드가 각 클래스마다 있지만 호출하는 메서드 이름이 달라서 각 클래스마다 메서드 이름을 확인해야 할때
- [] 인터페이스를 사용했을 때 이점을 이해하는가?
호출할 때 일관성이 있도록 호출규칙을 정의하는 전문적인 문법인 인터페이스 클래스이다.
- [] 인터페이스의 default 메서드의 용도를 설명할 수 있는가?
먼저 인터페이스의 메서드에서의 default는 아무것도 적은 것이 아닌 public이 생략된것이다.
(public)void play();
하지만 진짜 default 메서드는 직접 삽입해야한다
default play();
default 메서드는 기존 프로젝트에 영향을 끼치지 않으면서 기존 규칙에 새 메서드를 추가할 때 유용하다
인터페이스에서 미리 구현한 메서드이기 때문에 클래스에서 구현을 생략할 수 있다
반대로 구현을 강제할 수 없다는 것이 단점이다
즉 강제성에 구멍이 생긴다.
- [] 인터페이스의 상속과 다중 상속을 이해하는가?

인터페이스 다중상속은 추상클래스와 반대로 가능하다
이유는 같은 시그니처의 메서드가 양쪽 모두 있다하더라도 구현되지 않았기 때문에
어떤 메서드를 상속받더라도 문제가 되지 않는다
- [] 인터페이스의 다중 상속이 불가능한 경우를 설명할 수 있는가?

하지만 리턴타입이 다른 경우라면 오버로딩이 불가하다
왜냐하면 A와 B의 m1 메서드가 리턴타입이 서로 달라서 둘 중 어느것을 선택할수 없기 때문이다.
- [] 인터페이스의 구현과 다중 구현을 이해하는가?

다중 인터페이스도 이름과 리턴타입이 같더라도 구현되지 않았기에
문제가 되지 않는다.
- [] 인터페이스의 다중 구현이 불가능한 경우를 설명할 수 있는가?

다중 인터페이스에도 이름이 같으나 리턴타입이 다르면 둘중 어느 것을 선택할 수 없어 에러가 난다.