Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions TIL/sample/2026-06-15-캡슐화-컬렉션.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@

- Map: 키(key), 값(value)의 쌍으로 이루어진 요소를 담는 자료구조, 키의 중복은 허용되지 않는다.

- List의 for문은 일반 for 문과 다르다.
List<PersonList> personLists = new ArrayList<>();
personLists.add(new PersonList("홍길동", 20));
personLists.add(new PersonList("한석봉", 25));
- for 문의 다른 형식

for (PersonList name : personLists) {
System.out.println(name.getName() + "의 나이는 " + name.getAge() + "살");
}
List<PersonList> personLists = new ArrayList<>();
personLists.add(new PersonList("홍길동", 20));
personLists.add(new PersonList("한석봉", 25));

for (PersonList name : personLists) {
System.out.println(name.getName() + "의 나이는 " + name.getAge() + "살");
}

## 기억할 것

Expand Down Expand Up @@ -151,7 +152,7 @@ class ClericTest2 {

## 어려웠던 점

- List에서 for문을 다르게 작성한다는 것이 헷갈림?
- for문의 같으면서 다른 형식의 헷갈림?
- List외에도 Set, Map은 언제 어디서 써야 하나?

## 해결 방법
Expand Down
92 changes: 92 additions & 0 deletions TIL/sample/2026-06-16-상속.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# 2026-06-15 캡슐화-컬렉션

## 오늘 배운 내용

- 상속: 이전에 만든 클래스와 닮았지만, 일부 다른 클래스 를 만들 필요가 있을 경우가 늘어날 것이다.
- extends 로 상속을 쓴다.
- public class SuperHero extends Hero
- SuperHero가 자식 클래스 이름, Hero가 부모 클래스
- boolean 같은 경우 private로 하고 getter 만들때 is를 붙이는게 관습이다.
- private boolean isFlying;
- public boolean isFlying(){return isFlying;}
- 다중상속은 Java에서는 금지

- final을 쓰면 상속을 막을 수가 있다.
- public final class String 하면 상속이 되지 않는다.

- 상속을 받은 생성자는 부모 생성자부터 호출 후 자식 생성자를 호출한다.
- 부모 클래스에 생성자가 없다면 자식 클래스에서 에러가 뜬다.
- 상속을 받으면 반드시 부모(super) 클래스의 생성자를 반드시 호출해야 된다.
- 해결방법
public SuperHero(String name, int hp){super(name,hp);}
- 단, 부모 클래스에 생성자가 있다면 에러가 나지는 않는다.

- 부모 클래스(위로(super))로 갈수록 추상적인 것으로 일반화가 되고, 자식 클래스 일 수록 구체화 된다.


- 오버라이드(Override)
- 부모 클래스에 있는 메서드를 자식 클래스에서 재정의 하는 것
- 상속 받은 메서드를 재정의

- 메서드도 부모 클래스에 final 이 있다면 상속을 막을 수 있다.
- public final void slip()
- public void attack() { super.attack(); << 상속 받은 것.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

불완전한 코드 예제를 수정하세요.

라인 33의 코드 조각이 미완성 상태입니다. 주석 표기 "<<" 가 있고 메서드 본문이 제대로 작성되지 않았습니다. 명확한 예제 코드로 교체하거나 설명 텍스트로 변경하는 것이 좋습니다.

💡 개선 제안

라인 33을 다음과 같이 개선할 수 있습니다:

-    - public void attack() { super.attack(); << 상속 받은 것.
+    - 예: `super.attack();` 로 부모 클래스의 메서드를 호출할 수 있습니다.

또는 완전한 예제:

`@Override`
void attack(Hero hero) {
    super.attack(hero);  // 부모 클래스의 attack 호출
    // 추가 로직...
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TIL/sample/2026-06-16-상속.md` at line 33, The code example for the attack()
method at line 33 is incomplete and malformed with an improper comment notation
"<<" that breaks the code syntax. Replace this incomplete line with a complete,
well-formed code example that demonstrates method overriding with a proper
`@Override` annotation, a complete method signature including parameters if
needed, a call to the parent class method using super.attack(), and proper
closing braces. Ensure the example is syntactically correct and clearly
illustrates the inheritance concept being documented.



- 어노테이션 (주석)
- @Override 같은 것들

## 기억할 것

- 상속 받은 메서드도 재정의를 할 수 있다.
- 그 외 오늘 배운 내용을 메모 한 것을 기억해야 한다.

=========

## 실습 코드

```java
package com.survivalcoding;

public class GreatWizard extends Wizard {
private int maxHp = 300;

GreatWizard(String name, int hp, int mp) {
super(name, hp, mp);
setMp(150);
}

@Override
void heal() {
if (getMp() < 5) {
System.out.println("마나가 부족합니다.");
} else {
setMp(getMp() - 5);
setHp(getHp() + 25);
System.out.println("힐을 시전했습니다. " + getName() + " HP : " + getHp());
}
}
Comment on lines +60 to +68

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

TIL 실습 코드의 메서드 시그니처가 실제 구현과 불일치합니다. TIL 문서의 GreatWizard 예제는 Hero 파라미터 없이 작성되었으나, 실제 game/src/main/java/com/survivalcoding/GreatWizard.java와 테스트 케이스(game/src/test/java/com/survivalcoding/GreatWizardTest.java)에서는 모두 Hero 파라미터를 요구합니다. 이러한 불일치는 학습자가 작성한 코드와 실제 프로젝트 코드 사이에 큰 혼동을 초래할 수 있습니다.

  • TIL/sample/2026-06-16-상속.md#L60-L68: heal() 메서드 시그니처를 heal(Hero hero)로 수정하고, 메서드 본문에서 hero.setHp(hero.getHp() + 25)로 변경하여 실제 구현을 반영합니다.
  • TIL/sample/2026-06-16-상속.md#L70-L79: superHeal() 메서드 시그니처를 superHeal(Hero hero)로 수정하고, hero.setHp(hero.getMaxHp())로 수정하여 Hero의 HP를 최대값으로 복구하도록 합니다.
📍 Affects 1 file
  • TIL/sample/2026-06-16-상속.md#L60-L68 (this comment)
  • TIL/sample/2026-06-16-상속.md#L70-L79
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TIL/sample/2026-06-16-상속.md` around lines 60 - 68, The TIL documentation has
method signatures that differ from the actual project implementation. At
TIL/sample/2026-06-16-상속.md lines 60-68, update the heal() method signature to
accept a Hero parameter as heal(Hero hero), and change the method body to call
hero.setHp(hero.getHp() + 25) instead of setHp(getHp() + 25). Similarly, at
TIL/sample/2026-06-16-상속.md lines 70-79, update the superHeal() method signature
to accept a Hero parameter as superHeal(Hero hero), and change the method body
to call hero.setHp(hero.getMaxHp()) to restore the Hero's HP to maximum. These
changes align the TIL documentation with the actual implementation in
game/src/main/java/com/survivalcoding/GreatWizard.java and its corresponding
test cases.


void superHeal() {
if (getMp() < 50) {
System.out.println("마나가 부족합니다.");
} else {
setMp(getMp() - 50);
setHp(maxHp);
System.out.println("슈퍼 힐을 시전했습니다. " + getName() + " HP : " + getHp());
}
}
}
```

## 어려웠던 점

- 어렵다기보다 헷갈린 점인데, 상속 받은 후에 super 클래스에서 private 면 get, set을 써야한다는 점

## 해결 방법

- 연습 말고는 없음

## 내일 더 공부할 것

- 부모,자식 클래스를 만들어서 여러 번 해보는 것
Binary file added game/game.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions game/game.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@startuml
scale 1

class GreatWizard extends Wizard {
-int maxHp = 300
+GreatWizard(String:name, int:hp, int:mp
<<super(name,hp,np)>>, setMp(150))
Comment on lines +6 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

GreatWizard 생성자 표기 오타(np)와 시그니처 표현이 코드와 불일치합니다.

Line 7의 super(name,hp,np)mp 오타이고, 현재 줄바꿈 형태도 생성자 시그니처를 잘못 읽히게 만듭니다. 다이어그램을 코드 시그니처와 동일하게 정리해 주세요.

🔧 제안 수정안
-    +GreatWizard(String:name, int:hp, int:mp
-    <<super(name,hp,np)>>, setMp(150))
+    +GreatWizard(String:name, int:hp, int:mp, <<super(name,hp,mp)>>, setMp(150))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
+GreatWizard(String:name, int:hp, int:mp
<<super(name,hp,np)>>, setMp(150))
GreatWizard(String:name, int:hp, int:mp, <<super(name,hp,mp)>>, setMp(150))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@game/game.puml` around lines 6 - 7, Fix the typo in the GreatWizard
constructor notation on line 7 where the super call contains `np` which should
be `mp` to match the parameter defined on line 6. Additionally, reformat the
constructor signature for the GreatWizard class to clearly and consistently
represent the full constructor declaration including its parameters, parent
class invocation with the corrected parameter name, and method calls, ensuring
the PlantUML diagram matches the actual code signature.

+<<override>>void heal(Hero hero)
+void superHeal(Hero hero)
}

class Wizard {
-String name
-int hp
-int mp = 100
-Wand wand

+Wizard(String:name, int:hp, int:mp, Wand:wand)
+Wizard(String:name, int:hp, int:mp)
+void heal(Hero hero)
}


class PoisonSlime extends Slime {
-int poisonCount = 5

+PoisonSlime(String:suffix<<super(suffix)>>)
+<<override>>void attack(Hero hero)
}

class Slime {
-final String suffix
-int hp = 100

+Slime(String:suffix)
+void attack(Hero hero)
}

class Hero {
-String name;
-int hp;
-int maxHp = 300;

+Hero(String name, int hp)
+void attack()
}


@enduml
31 changes: 31 additions & 0 deletions game/src/main/java/com/survivalcoding/GreatWizard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.survivalcoding;

public class GreatWizard extends Wizard {
private int maxHp = 300;

GreatWizard(String name, int hp, int mp) {
super(name, hp, mp);
setMp(150);
}

@Override
void heal(Hero hero) {
if (getMp() < 5) {
System.out.println("마나가 부족합니다.");
} else {
setMp(getMp() - 5);
hero.setHp(hero.getHp() + 25);
System.out.println("힐을 시전했습니다. " + hero.getName() + " HP : " + hero.getHp());
}
}

void superHeal(Hero hero) {
if (getMp() < 50) {
System.out.println("마나가 부족합니다.");
} else {
setMp(getMp() - 50);
hero.setHp(hero.getMaxHp());
System.out.println("슈퍼 힐을 시전했습니다. " + hero.getName() + " HP : " + hero.getHp());
}
}
}
25 changes: 24 additions & 1 deletion game/src/main/java/com/survivalcoding/Hero.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
package com.survivalcoding;

public class Hero {
String name;
private String name;
private int hp;
private int maxHp = 300;

Hero(String name, int hp) {
setName(name);
setHp(hp);
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getMaxHp() {
return maxHp;
}

public void setMaxHp(int maxHp) {
this.maxHp = maxHp;
}
Comment on lines +25 to +27

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

setMaxHp가 Hero 상태 불변식을 깨뜨릴 수 있습니다.

Line 25-27에서 maxHp를 그대로 대입하면 음수 값이나 현재 HP보다 작은 값이 들어갈 수 있고, 이후 GreatWizard.superHeal(...)(game/src/main/java/com/survivalcoding/GreatWizard.java Line 27) 경로에서 예외/비정상 상태로 이어질 수 있습니다. maxHp >= 0 검증과 hp <= maxHp 보정을 함께 넣는 편이 안전합니다.

🔧 제안 수정안
 public void setMaxHp(int maxHp) {
-    this.maxHp = maxHp;
+    if (maxHp < 0) {
+        throw new IllegalArgumentException("최대 HP는 0 이상이어야 합니다.");
+    }
+    this.maxHp = maxHp;
+    if (this.hp > maxHp) {
+        this.hp = maxHp;
+    }
 }
 public void setHp(int hp) {
     if (hp < 0) {
         throw new IllegalArgumentException("HP는 0 이상이어야 합니다.");
     }
-    this.hp = hp;
+    this.hp = Math.min(hp, maxHp);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@game/src/main/java/com/survivalcoding/Hero.java` around lines 25 - 27, The
setMaxHp method in the Hero class does not validate its input or maintain the
Hero state invariant that hp should never exceed maxHp. Add validation to ensure
the new maxHp is non-negative (maxHp >= 0), and if the current hp exceeds the
new maxHp after assignment, reduce hp to equal the new maxHp value. This
prevents violations of the Hero state invariant that could cause issues in
downstream code like GreatWizard.superHeal().


public int getHp() {

return hp;
}

Expand Down
29 changes: 29 additions & 0 deletions game/src/main/java/com/survivalcoding/PoisonSlime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.survivalcoding;

public class PoisonSlime extends Slime {
private int poisonCount = 5;

public PoisonSlime(String suffix) {
super(suffix);
}

public int getPoisonCount() {
return poisonCount;
}

@Override
void attack(Hero hero) {
if (poisonCount > 0) {
super.attack(hero);
System.out.println("추가로, 독 포자를 살포했다!");
int poisonDamage = hero.getHp() / 5;
hero.setHp(hero.getHp() - poisonDamage);
System.out.println(poisonDamage + "포인트 데미지");
poisonCount--;
}
if (poisonCount <= 0) {
super.attack(hero);
}
Comment on lines +16 to +26

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

독 카운트가 1일 때 기본 공격이 한 번 더 적용됩니다.

Line 16-26은 poisonCount == 1인 호출에서 첫 번째 블록 실행 후 poisonCount--로 0이 되고, 바로 아래 조건도 참이 되어 super.attack(hero)가 같은 턴에 2회 실행됩니다.

🔧 제안 수정안
 `@Override`
 void attack(Hero hero) {
     if (poisonCount > 0) {
         super.attack(hero);
         System.out.println("추가로, 독 포자를 살포했다!");
         int poisonDamage = hero.getHp() / 5;
         hero.setHp(hero.getHp() - poisonDamage);
         System.out.println(poisonDamage + "포인트 데미지");
         poisonCount--;
-    }
-    if (poisonCount <= 0) {
+        return;
+    }
+    if (poisonCount <= 0) {
         super.attack(hero);
     }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@game/src/main/java/com/survivalcoding/PoisonSlime.java` around lines 16 - 26,
The issue is that when poisonCount equals 1, both the first if block
(poisonCount > 0) and the second if block (poisonCount <= 0) execute in the same
turn, causing super.attack(hero) to be called twice. The first block decrements
poisonCount to 0, which then satisfies the second condition. Fix this by
changing the second if statement to else if, so that only one attack path is
executed per method call. Specifically, replace the second if (poisonCount <= 0)
condition with else if (poisonCount <= 0) to ensure the basic attack only
executes when there is no poison attack in that turn.

}

}
28 changes: 28 additions & 0 deletions game/src/main/java/com/survivalcoding/Slime.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.survivalcoding;

public class Slime {
private final String suffix;
private int hp = 100;

public Slime(String suffix) {
this.suffix = suffix;
}

public String getSuffix() {
return suffix;
}

public int getHp() {
return hp;
}

public void setHp(int hp) {
this.hp = hp;
}

void attack(Hero hero) {
System.out.println("슬라임 " + suffix + "이/가 공격했다");
System.out.println("10의 데미지");
hero.setHp(hero.getHp() - 10);
}
}
26 changes: 22 additions & 4 deletions game/src/main/java/com/survivalcoding/Wizard.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class Wizard {
private int hp;
private int mp;
private int mp = 100;
private String name;
private Wand wand;

Expand All @@ -21,7 +21,14 @@ public class Wizard {
}
}

Wizard(String name, int hp, int mp) {
setName(name);
setHp(hp);
setMp(mp);
}

public Wand getWand() {

return wand;
}

Expand Down Expand Up @@ -69,8 +76,19 @@ public void setName(String name) {
}

void heal(Hero hero) {
int basePoint = 10;
int recovPoint = (int) (basePoint * this.wand.getPower());
hero.setHp(hero.getHp() + recovPoint);
if (this.mp < 10) {
System.out.println("마나가 부족합니다.");
} else {
this.mp -= 10;
hero.setHp(hero.getHp() + 20);
System.out.println("힐을 시전했습니다. " + hero.getName() + " HP : " + hero.getHp());
}
}
}
// 이전 heal 메서드
// void heal(Hero hero) {
// int basePoint = 10;
// int recovPoint = (int) (basePoint * this.wand.getPower());
// hero.setHp(hero.getHp() + recovPoint);
// }

Loading