Skip to content

Commit 10c1cef

Browse files
authored
Add files via upload
1 parent ff8bd86 commit 10c1cef

5 files changed

Lines changed: 248 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package week03.basic;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class AbstractShapeArea {
7+
8+
public static void main(String[] args) {
9+
System.out.println("<추상 골격 제공 + 구현 클래스>");
10+
// B-3) 추상 골격 제공 + 구현 클래스
11+
// 문제: `abstract class Shape { abstract double area(); }`를 만들고,
12+
// `Rectangle(w,h)`와 `Circle(r)`이 `area()`를 구현하도록 하라. 리스트에 담아 총 넓이를 구해보라.
13+
// 문제설명: 추상 클래스는 공통 인터페이스(시그니처)를 강제하고, 하위 클래스가 구현 세부를 제공한다.
14+
// 클라이언트는 상위 타입 `Shape`로 묶어 다룰 수 있고, 런타임에는 실제 타입의 `area()`가 호출된다(동적 바인딩).
15+
// 힌트: `abstract class`, `abstract method`, `implements` 아님(클래스 상속), 리스트,
16+
// 향상된 for, 다형성.
17+
Shape r1 = new Rectangle(8,7);
18+
Shape r2 = new Rectangle(5,2);
19+
Shape r3 = new Rectangle(9,3);
20+
21+
Shape c1 = new Circle(4);
22+
Shape c2 = new Circle(6);
23+
24+
List<Shape> list = new ArrayList<>();
25+
list.add(r1);
26+
list.add(r2);
27+
list.add(r3);
28+
list.add(c1);
29+
list.add(c2);
30+
31+
double sum = 0.0;
32+
for (Shape s : list) {
33+
sum += s.area();
34+
}
35+
System.out.println("총 넓이: " + sum);
36+
37+
}
38+
39+
}
40+
41+
abstract class Shape { // 추상 클래스(추상 메서드가 있으면 그 구현을 하위 클래스에 강제한다)
42+
abstract double area();
43+
}
44+
45+
class Rectangle extends Shape {
46+
private double width;
47+
private double height;
48+
49+
Rectangle(double width, double height) { //생성자
50+
this.width = width;
51+
this.height = height;
52+
}
53+
54+
@Override
55+
double area() { // 추상 메서드
56+
return width * height;
57+
}
58+
59+
}
60+
61+
class Circle extends Shape {
62+
private double r;
63+
64+
Circle(double r) { //생성자
65+
this.r = r;
66+
}
67+
68+
@Override
69+
double area() { // 추상 메서드
70+
return r * r * Math.PI;
71+
}
72+
73+
}

week03/basic/InterfaceReport.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package week03.basic;
2+
3+
public class InterfaceReport {
4+
5+
public static void main(String[] args) {
6+
System.out.println("<인터페이스 계약과 다중 구현>");
7+
// B-4) 인터페이스 계약과 다중 구현
8+
// 문제: `interface Printable { void print(); }`와
9+
// `interface Exportable { String format(); }`를 정의하고,
10+
// 'Report`가 둘 다 `implements` 하도록 하라. `print()`는 `format()` 결과를 출력한다.
11+
// 문제설명: 인터페이스는 행동 계약만 정의하며 여러 개를 동시에 구현할 수 있다.
12+
// 구현체는 두 계약을 모두 만족해야 하며, 호출부는 인터페이스 타입으로 의존하면 유연성이 커진다.
13+
// 힌트: `interface`, `implements`, 다중 인터페이스 구현, 업캐스팅(Report → Printable/Exportable).
14+
Printable p = new Report("Day1");
15+
p.print();
16+
17+
}
18+
19+
}
20+
// implements -> 계약을 이행하겠다고 선언
21+
class Report implements Printable, Exportable {
22+
23+
private String title;
24+
25+
Report(String title){
26+
this.title = title;
27+
}
28+
29+
@Override
30+
public String format() {
31+
return title;
32+
}
33+
34+
@Override
35+
public void print() {
36+
System.out.println(format());
37+
}
38+
39+
}
40+
41+
// 인터페이스 -> 계약서
42+
interface Printable { // 출력할 수 있어야함.
43+
void print();
44+
45+
}
46+
47+
interface Exportable { // 문자열로 표현할 수 있어야함.
48+
String format();
49+
50+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package week03.basic;
2+
3+
public class OverrideMessagePrinter {
4+
5+
public static void main(String[] args) {
6+
System.out.println("<오버라이드로 출력 포맷 바꾸기>");
7+
// B-1) 오버라이드로 출력 포맷 바꾸기
8+
// 문제: `MessagePrinter`의 `print(String msg)`는 `msg`를 그대로 반환한다.
9+
// `TimestampPrinter`가 이를 상속받아 `print`를 오버라이드하여 `"[INFO] msg"` 형태로 반환하도록 고쳐라.
10+
// 테스트용으로 부모/자식 인스턴스를 각각 만들어 호출해보라.
11+
// 문제설명: 오버라이드는 메서드 시그니처(리턴타입/이름/매개변수)를 동일하게 유지한 채 구현만 바꾸는 것이다.
12+
// 자식에서 부모의 메서드와 동일한 시그니처로 선언하고 `@Override`를 붙이면 컴파일 타임에 검증된다.
13+
// `this`는 현재 인스턴스를 가리키며, 필요하면 `super.print(msg)` 결과를 조합할 수도 있다.
14+
// 힌트: `class A { String print(...) }`, `class B extends A`, `@Override`, `super`
15+
// ,`this`, 다형성(부모 타입 변수로 자식 참조 저장 가능).
16+
MessagePrinter mp = new MessagePrinter();
17+
System.out.println(mp.print("Hello"));
18+
19+
TimestampPrinter tp = new TimestampPrinter();
20+
System.out.println(tp.print("Hello"));
21+
22+
}
23+
24+
}
25+
26+
class MessagePrinter {
27+
28+
String print(String msg){
29+
return msg;
30+
}
31+
32+
}
33+
34+
class TimestampPrinter extends MessagePrinter{
35+
36+
@Override
37+
String print(String msg) {
38+
String info = "[INFO] ";
39+
return info + super.print(msg);
40+
}
41+
42+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package week03.basic;
2+
3+
public class SafeDowncastAnimal {
4+
5+
public static void main(String[] args) {
6+
System.out.println("<업캐스팅/다운캐스팅 안전 체크>");
7+
// B-5) 업캐스팅/다운캐스팅 안전 체크
8+
// 문제: `Animal`을 상위로, `Dog`(메서드 `wag()`), `Cat`을 하위로 만든다.
9+
// `Animal`을 인자로 받아 Dog인 경우에만 `wag()`를 호출하고 true를, 아니면 false를 반환하는 함수를 작성하라.
10+
// 문제설명: 부모 타입으로 받은 참조는 실제로 자식일 수 있다(업캐스팅).
11+
// 자식 전용 기능을 쓰려면 다운캐스팅이 필요한데, 안전을 위해 런타임 타입 검사가 필요하다.
12+
// 힌트: 업캐스팅(자동), `instanceof`, 다운캐스팅, 다형성.
13+
Animal a1 = new Dog(); // 업캐스팅(자동): 실제 객체는 Dog, 참조 타입은 Animal
14+
System.out.println("Dog: " + checkDog(a1));
15+
16+
Animal a2 = new Cat();
17+
System.out.println("Cat: " + checkDog(a2));
18+
19+
}
20+
// 다운캐스팅 : 더 구체적인 신분증을 보여주는 것(ex. 직원증 -> 개발자)
21+
// 새 변수의 선언타입(원시타입 or 참조타입) 새 변수 이름 = (캐스트 연산자) 캐스트 대상
22+
// 어디 있는지 알려주는 주소표 (ex. d.name() -> d(화사표)를 따라가서 Dog의 name 필드 값을 읽어옴.)
23+
// 캐스트 연산자 -> 지금 이 타입으로 보겠다. (ex. (int)3.14 -> 정수 타입으로 보겠다.)
24+
static boolean checkDog(Animal animal){
25+
if (animal == null) return false; // 가드절 -> 즉시 종료(빠르게 걸러내기)
26+
if (animal instanceof Dog) {
27+
Dog d = (Dog) animal; // ← 다운캐스팅: ‘Dog 관점’으로 보겠다
28+
return d.wag();
29+
}
30+
return false;
31+
}
32+
}
33+
34+
class Animal {
35+
36+
}
37+
38+
class Dog extends Animal {
39+
public boolean wag() {
40+
return true;
41+
}
42+
}
43+
44+
class Cat extends Animal {
45+
46+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package week03.basic;
2+
3+
public class SuperPrefixLogger {
4+
5+
public static void main(String[] args) {
6+
System.out.println("<super 재사용: 기본 동작 + 추가 문구>");
7+
// B-2) super 재사용: 기본 동작 + 추가 문구
8+
// 문제: `BaseLogger.log(String msg)`는 `msg`를 반환한다. `PrefixLogger`는 이를 상속받아,
9+
// 먼저 `super.log(msg)`를 호출한 뒤 결과 앞에 `"[PREFIX] "`를 붙여 반환하라.
10+
// 문제설명: 자식이 부모의 기본 동작을 활용하고 싶을 때 `super`로 부모 메서드를 호출한다.
11+
// 이 패턴은 행동 확장(decorate) 예시다. 동일 시그니처를 유지하므로 클라이언트 코드는
12+
// 자식 객체를 부모 타입으로 다뤄도 동작이 교체된다(다형성).
13+
// 힌트: 상속, `@Override`, `super.log(...)`, 다형성(업캐스팅).
14+
BaseLogger b = new BaseLogger();
15+
System.out.println(b.log("접두사"));
16+
17+
PrefixLogger p = new PrefixLogger();
18+
System.out.println(p.log("접두사"));
19+
}
20+
21+
}
22+
23+
class BaseLogger{
24+
String log(String msg) {
25+
return msg;
26+
}
27+
}
28+
29+
class PrefixLogger extends BaseLogger {
30+
31+
@Override
32+
String log(String msg) {
33+
String pre = "[PREFIX] ";
34+
return pre + super.log(msg);
35+
}
36+
37+
}

0 commit comments

Comments
 (0)