-
Notifications
You must be signed in to change notification settings - Fork 18
260616_20_이종재 #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jongjae0305
wants to merge
2
commits into
SurvivalCodingCampus:student/20_이종재
Choose a base branch
from
jongjae0305:main
base: student/20_이종재
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
260616_20_이종재 #51
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # 2026-06-15 | ||
|
|
||
| ## 오늘 배운 내용 | ||
|
|
||
| ### 1. 캡슐화 | ||
|
|
||
| - 캡슐화는 필드를 외부에서 직접 변경하지 못하게 숨기고, 메소드를 통해 안전하게 접근하도록 만드는 것이다. | ||
| - 필드는 보통 `private`으로 선언한다. | ||
| - 값을 읽을 때는 getter, 값을 변경할 때는 setter를 사용한다. | ||
| - setter 안에서 잘못된 값이 들어오지 않도록 검사를 할 수 있다. | ||
| - 잘못된 값이 들어오면 `IllegalArgumentException`을 발생시켜 프로그램을 중단할 수 있다. | ||
|
|
||
| ```java | ||
| public void setName(String name) { | ||
| if (name == null || name.length() < 3) { | ||
| throw new IllegalArgumentException("이름은 null일 수 없고 3문자 이상이어야 합니다."); | ||
| } | ||
| this.name = name; | ||
| } | ||
| ``` | ||
|
|
||
| ### 2. 객체가 자기 값을 책임진다 | ||
|
|
||
| - `Wand`는 지팡이의 이름과 마력을 스스로 검사한다. | ||
| - `Wizard`는 마법사의 이름, HP, MP, 지팡이 장착 여부를 스스로 검사한다. | ||
| - `Wizard.setWand()`에서 지팡이 이름이나 마력까지 다시 검사할 필요는 없다. | ||
| - 지팡이의 상태는 `Wand`가 책임지고, 마법사의 상태는 `Wizard`가 책임진다. | ||
|
|
||
| ```java | ||
| public void setWand(Wand wand) { | ||
| if (wand == null) { | ||
| throw new IllegalArgumentException("마법사의 지팡이는 null일 수 없습니다."); | ||
| } | ||
| this.wand = wand; | ||
| } | ||
| ``` | ||
|
|
||
| ### 3. List, Set, Map | ||
|
|
||
| - `List` | ||
| - 순서가 있다. | ||
| - 중복을 허용한다. | ||
| - 예: 학생 10명의 시험 점수 | ||
|
|
||
| - `Set` | ||
| - 순서가 중요하지 않다. | ||
| - 중복을 허용하지 않는다. | ||
| - 예: 대한민국의 도시 이름 모음 | ||
|
|
||
| - `Map` | ||
| - key와 value를 한 쌍으로 저장한다. | ||
| - 예: 도시별 인구수, 이름별 나이 | ||
|
|
||
| ```java | ||
| Map<String, Integer> ages = new LinkedHashMap<>(); | ||
|
|
||
| ages.put("홍길동", 20); | ||
| ages.put("한석봉", 25); | ||
| ``` | ||
|
|
||
| ## 기억할 것 | ||
|
|
||
| ### 캡슐화 | ||
|
|
||
| - 필드는 직접 접근하지 못하게 `private`으로 만든다. | ||
| - 외부에서는 getter와 setter를 통해 접근한다. | ||
| - setter는 단순히 값을 넣는 역할만 하는 것이 아니라, 값이 올바른지 검사하는 역할도 한다. | ||
|
|
||
| ```java | ||
| private int mp; | ||
|
|
||
| public void setMp(int mp) { | ||
| if (mp < 0) { | ||
| throw new IllegalArgumentException("MP는 0 이상이어야 합니다."); | ||
| } | ||
| this.mp = mp; | ||
| } | ||
| ``` | ||
|
|
||
| ### 컬렉션 선택 기준 | ||
|
|
||
|
|
||
| | 기준 | 컬렉션 | | ||
| |--|---| | ||
| | `List` | 중복을 허용하고 순서가 필요하면 | | ||
| |`Set` | 중복을 막고 싶으면| | ||
| |`Map` | 이름과 나이처럼 쌍으로 저장하면| | ||
|
|
||
|
|
||
| ## 실습 코드 | ||
|
|
||
| ### Person 리스트 | ||
|
|
||
| ```java | ||
| List<Person> people = new ArrayList<>(); | ||
|
|
||
| people.add(new Person("홍길동")); | ||
| people.add(new Person("한석봉")); | ||
|
|
||
| for (Person person : people) { | ||
| System.out.println(person.getName()); | ||
| } | ||
| ``` | ||
|
|
||
| ### 이름과 나이를 Map에 저장 | ||
|
|
||
| ```java | ||
| Map<String, Integer> ages = new LinkedHashMap<>(); | ||
|
|
||
| ages.put("홍길동", 20); | ||
| ages.put("한석봉", 25); | ||
|
|
||
| for (Map.Entry<String, Integer> entry : ages.entrySet()) { | ||
| System.out.println(entry.getKey() + "의 나이는 " + entry.getValue() + "살"); | ||
| } | ||
| ``` | ||
|
|
||
| ## 어려웠던 점 | ||
|
|
||
| - 처음에는 `private`으로 필드를 숨기면 코드가 더 복잡해지는 것처럼 느껴졌다. | ||
| - 하지만 setter에서 잘못된 값을 막을 수 있어서 객체의 상태를 안전하게 유지할 수 있다는 점을 알게 되었다. | ||
| - `List`, `Set`, `Map`은 이름은 익숙했지만, 어떤 상황에서 무엇을 써야 하는지 구분하는 것이 헷갈렸다. | ||
|
|
||
| ## 해결 방법 | ||
|
|
||
| - 값 하나하나를 어디서 검사해야 하는지 생각했다. | ||
| - `Wand`의 값은 `Wand`가 검사하고, `Wizard`의 값은 `Wizard`가 검사하도록 나누었다. | ||
| - 컬렉션은 저장하려는 데이터의 특징을 먼저 보고 골랐다. | ||
|
|
||
| ## 내일 더 공부할 것 | ||
|
|
||
| - 상속 | ||
| - 오버라이딩 | ||
| - 추상 클래스 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,241 @@ | ||
| # 2026-06-16 | ||
|
|
||
| ## 오늘 배운 내용 | ||
|
|
||
| ### 1. 오버라이딩 | ||
|
|
||
| - 오버라이딩은 부모 클래스가 가진 메서드를 자식 클래스에서 다시 정의하는 것이다. | ||
| - 자식 클래스는 부모 클래스의 기능을 그대로 물려받을 수 있지만, 필요하면 자신의 상황에 맞게 메서드 내용을 바꿀 수 있다. | ||
| - 오버라이딩을 할 때는 부모 메서드와 이름, 매개변수, 리턴 타입이 같아야 한다. | ||
| - 오버라이딩한 메서드 위에는 `@Override`를 붙이는 것이 좋다. | ||
| - `@Override`를 붙이면 메서드 이름이나 매개변수를 잘못 작성했을 때 컴파일러가 알려준다. | ||
|
|
||
| ```java | ||
| class Wizard { | ||
| public void heal(Hero hero) { | ||
| hero.setHp(hero.getHp() + 20); | ||
| } | ||
| } | ||
|
|
||
| class GreatWizard extends Wizard { | ||
| @Override | ||
| public void heal(Hero hero) { | ||
| hero.setHp(hero.getHp() + 25); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### 2. 부모 메서드 호출 | ||
|
|
||
| - 자식 클래스에서 오버라이딩을 했더라도 부모의 메서드를 호출할 수 있다. | ||
| - 이때 `super.메서드명()`을 사용한다. | ||
| - 부모의 기본 동작을 먼저 실행하고, 자식 클래스에서 추가 동작을 붙이고 싶을 때 사용한다. | ||
|
|
||
| ```java | ||
| class Slime { | ||
| public void attack(Hero hero) { | ||
| hero.setHp(hero.getHp() - 10); | ||
| } | ||
| } | ||
|
|
||
| class PoisonSlime extends Slime { | ||
| @Override | ||
| public void attack(Hero hero) { | ||
| super.attack(hero); | ||
|
|
||
| int poisonDamage = hero.getHp() / 5; | ||
| hero.setHp(hero.getHp() - poisonDamage); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### 3. 오버라이딩과 다형성 | ||
|
|
||
| - 부모 타입 변수에 자식 인스턴스를 담을 수 있다. | ||
| - 이때 메서드를 호출하면 실제 인스턴스의 오버라이딩된 메서드가 실행된다. | ||
| - 이것을 다형성이라고 한다. | ||
|
|
||
| ```java | ||
| Wizard wizard = new GreatWizard(); | ||
|
|
||
| wizard.heal(hero); // GreatWizard의 heal() 실행 | ||
| ``` | ||
|
|
||
| ## 기억할 것 | ||
|
|
||
| ### 오버로딩과 오버라이딩 차이 | ||
|
|
||
| | 구분 | 오버로딩 | 오버라이딩 | | ||
| |---|---|---| | ||
| | 관계 | 같은 클래스 안에서 사용 | 상속 관계에서 사용 | | ||
| | 메서드 이름 | 같아야 함 | 같아야 함 | | ||
| | 매개변수 | 달라야 함 | 같아야 함 | | ||
| | 리턴 타입 | 상관없지만 리턴 타입만 다르면 안 됨 | 같아야 함 | | ||
| | 목적 | 같은 이름으로 여러 기능 제공 | 부모 기능을 자식 방식으로 변경 | | ||
|
|
||
| ### `@Override` | ||
|
|
||
| - 오버라이딩한 메서드에는 `@Override`를 붙인다. | ||
| - 오타나 매개변수 차이로 오버라이딩이 안 되는 실수를 막을 수 있다. | ||
|
|
||
| ```java | ||
| @Override | ||
| public void attack(Hero hero) { | ||
| super.attack(hero); | ||
| } | ||
| ``` | ||
|
|
||
| ### `super` | ||
|
|
||
| - `super`는 부모 클래스를 가리킨다. | ||
| - `super.attack(hero)`처럼 사용하면 부모 클래스의 메서드를 실행할 수 있다. | ||
| - 부모의 기능을 유지하면서 자식 클래스의 기능을 추가할 때 유용하다. | ||
|
|
||
| ## 실습 코드 | ||
|
|
||
| ### Wizard와 GreatWizard | ||
|
|
||
| ```java | ||
| package com.survivalcoding.day260616; | ||
|
|
||
| public abstract class Wizard { | ||
| private int mp = 100; | ||
|
|
||
| public void heal(Hero hero) { | ||
| int recovPoint = 20; | ||
|
|
||
| if (this.mp < 10) { | ||
| System.out.println("마나가 부족합니다"); | ||
| return; | ||
| } | ||
|
|
||
| hero.setHp(hero.getHp() + recovPoint); | ||
| setMp(getMp() - 10); | ||
| System.out.println("힐을 시전했습니다. 대상 HP : " + hero.getHp()); | ||
| } | ||
|
|
||
| public int getMp() { | ||
| return mp; | ||
| } | ||
|
|
||
| public void setMp(int mp) { | ||
| if (mp < 0) { | ||
| throw new IllegalArgumentException("마법사의 MP는 0 이상이어야 합니다."); | ||
| } | ||
| this.mp = mp; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ```java | ||
| package com.survivalcoding.day260616; | ||
|
|
||
| public class GreatWizard extends Wizard { | ||
| public GreatWizard() { | ||
| setMp(150); | ||
| } | ||
|
|
||
| @Override | ||
| public void heal(Hero hero) { | ||
| int recovPoint = 25; | ||
|
|
||
| if (getMp() < 5) { | ||
| System.out.println("마나가 부족합니다"); | ||
| return; | ||
| } | ||
|
|
||
| hero.setHp(hero.getHp() + recovPoint); | ||
| setMp(getMp() - 5); | ||
| System.out.println("힐을 시전했습니다. 대상 HP : " + hero.getHp()); | ||
| } | ||
|
|
||
| public void superHeal(Hero hero) { | ||
| if (getMp() < 50) { | ||
| System.out.println("마나가 부족합니다"); | ||
| return; | ||
| } | ||
|
|
||
| hero.setHp(hero.getMaxHp()); | ||
| setMp(getMp() - 50); | ||
| System.out.println("슈퍼 힐을 시전했습니다. 대상 HP : " + hero.getHp()); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Slime과 PoisonSlime | ||
|
|
||
| ```java | ||
| package com.survivalcoding.day260616; | ||
|
|
||
| public class Slime { | ||
| private final String suffix = "slime"; | ||
| private String name; | ||
| private int hp = 40; | ||
|
|
||
| public Slime(String name) { | ||
| this.name = name; | ||
| } | ||
|
|
||
| public void attack(Hero hero) { | ||
| System.out.println("슬라임" + suffix + "이/가 공격했다"); | ||
| System.out.println("10의 데미지"); | ||
|
|
||
| hero.setHp(hero.getHp() - 10); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ```java | ||
| package com.survivalcoding.day260616; | ||
|
|
||
| public class PoisonSlime extends Slime { | ||
| private int poisonCount = 5; | ||
|
|
||
| public PoisonSlime(String name) { | ||
| super(name); | ||
| } | ||
|
|
||
| @Override | ||
| public void attack(Hero hero) { | ||
| super.attack(hero); | ||
|
|
||
| if (this.poisonCount > 0) { | ||
| System.out.println("추가로, 독 포자를 살포했다!"); | ||
|
|
||
| int poisonDamage = hero.getHp() / 5; | ||
| hero.setHp(hero.getHp() - poisonDamage); | ||
|
|
||
| System.out.println(poisonDamage + "포인트 데미지!"); | ||
|
|
||
| this.poisonCount -= 1; | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## 어려웠던 점 | ||
|
|
||
| - 오버라이딩은 부모 메서드와 이름, 매개변수, 리턴 타입이 같아야 한다는 점이 중요했다. | ||
| - 자식 클래스에서 부모 클래스의 필드를 또 만들면 값이 따로 관리될 수 있다는 점이 헷갈렸다. | ||
| - 예를 들어 부모에도 `mp`가 있고 자식에도 `mp`가 있으면 `getMp()`와 `this.mp`가 서로 다른 값을 볼 수 있다. | ||
|
|
||
| ## 해결 방법 | ||
|
|
||
| - 오버라이딩할 때는 항상 `@Override`를 붙여서 실수를 줄였다. | ||
| - 부모의 기능을 먼저 사용해야 하는 경우에는 `super.attack(hero)`처럼 `super`를 사용했다. | ||
| - 자식 클래스에서는 부모와 같은 필드를 다시 만들지 않고, 부모의 getter와 setter를 사용하도록 정리했다. | ||
|
|
||
| ```java | ||
| if (getMp() < 5) { | ||
| System.out.println("마나가 부족합니다"); | ||
| return; | ||
| } | ||
|
|
||
| setMp(getMp() - 5); | ||
| ``` | ||
|
|
||
| ## 내일 더 공부할 것 | ||
|
|
||
| - 추상 클래스 | ||
| - 인터페이스 | ||
| - 다형성 | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
실습 코드 예시가 실제 구현과 달라 학습 포인트를 혼동시킬 수 있습니다.
GreatWizard생성자 예시가 실제 코드(super(150))와 달라서, 상속 생성자 체이닝 학습 맥락이 어긋납니다. 문서 예시를 실제 구현과 맞춰 주세요.문서 예시 정합성 수정안
public class GreatWizard extends Wizard { public GreatWizard() { - setMp(150); + super(150); }📝 Committable suggestion
🤖 Prompt for AI Agents