260616_02_김선진#55
Conversation
상속 개념 연습 구현학생이 Java 상속의 핵심 개념들을 실습 코드로 구현했습니다. 세 가지 주요 상속 관계를 다루었습니다: 1. Wizard → GreatWizard 상속
2. Slime → PoisonSlime 상속
3. 상속 기반 다형성 실습
주요 학습 성과학생은 테스트 코드의 실행 순서와 상태 관리의 중요성을 발견했습니다. 특히 테스트의 "When" 섹션에서 메서드 호출 순서가 결과에 미치는 영향을 이해하는 데 시간을 투자했으며, 이는 상속 구조에서 상태 변경(예: 독 카운트 감소)을 추적하는 능력을 강화했습니다. 고려할 개선 사항문서화 측면에서:
Walkthrough
ChangesJava 상속 실습 계층 구조 구현
추정 코드 리뷰 노력🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
game2/src/main/java/com/survivalcoding/Person.java (1)
4-4: ⚡ Quick win
age필드에서final제거로 인한 캡슐화 및 데이터 일관성 우려.Line 4에서
final int age→int age로 변경되면서 다음과 같은 설계 문제가 발생합니다:
- 데이터 일관성 깨짐: 생성자(line 10)에서
age = 2026 - birthYear로 계산되지만, 이제age를 직접 수정할 수 있어서birthYear와의 관계가 보장되지 않습니다.- 은닉 원칙 위반: age가 package-private 필드이므로 같은 패키지 내 코드에서 직접 수정 가능하며, 향후 public으로 노출되면 외부에서도 임의 수정 가능.
권장:
birthYear변경 시age를 함께 갱신하는 로직을setBirthYear()에 추가하거나,age는private로 유지하고getAge()메서드에서2026 - birthYear계산 후 반환하는 방식 검토💡 대안: age를 계산 속성으로 변경
public class Person { - int age; private String name; private int birthYear; Person(String name, int birthYear) { this.name = name; - this.age = 2026 - birthYear; + this.birthYear = birthYear; } + public int getAge() { + return 2026 - birthYear; + } // ... public static void main(String[] args) { Person person = new Person("Hong", 1998); System.out.println(person.getName()); - System.out.println(person.age); + System.out.println(person.getAge()); } }또는
setBirthYear()수정 시:public void setBirthYear(int birthYear) { this.birthYear = birthYear; + this.age = 2026 - birthYear; // age도 함께 갱신 }🤖 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 `@game2/src/main/java/com/survivalcoding/Person.java` at line 4, The `age` field in the Person class needs to restore encapsulation and data consistency. Either restore the `final` modifier to `age` and ensure it is only set in the constructor, or change `age` to `private` and modify the `getAge()` method to return the calculated value `2026 - birthYear` instead of storing it as a mutable field. If `setBirthYear()` exists or is added, ensure it recalculates `age` based on the new `birthYear` value to maintain consistency. This prevents external code or other parts of the class from breaking the invariant relationship between `birthYear` and `age`.game2/game2.puml (1)
1-59: 💤 Low valuePlantUML 문법 및 메서드 시그니처 정확성 개선 필요.
다이어그램이 전체 클래스 계층을 잘 보여주나, 다음과 같은 문법과 계약 누락이 있습니다:
필드 표기 오류:
- Line 8:
- int hp 100→ 올바른 PlantUML 문법은- int hp = 100메서드 표기 불명확:
- Line 5, 25:
+ run()+,+heal()+→ 끝의+는 제거하고 반환 타입 추가:+ void run(),+ void heal()- Line 26:
+superHeal()→+ void superHeal()로 명확히, 그리고 실제 구현(game2/src/main/java/com/survivalcoding/GreatWizard.java:35-50)에 따르면 매개변수Hero hero필요메서드 시그니처 완성도:
- Line 34-35:
+ setWand(),+ heal()→ 실제 구현의 매개변수와 반환 타입 표기 누락. 정확한 시그니처:+ void setWand(Wand),+ void heal(Hero)- Line 55:
+attack()(Slime) →+ void attack(Hero)또는+ void attack()명확히💡 제안: 메서드 시그니처 개선 예시
class SuperHero extends Hero { +void setFlying(bool flying) +boolean isFlying() - + run()+ + + void run() } class GreatWizard extends Wizard { - +heal()+ - +superHeal() + + void heal(Hero) + + void superHeal(Hero) } class Wizard { - int hp - int mp = 100 - Wand wand - String name + void setWand(Wand) - + heal() + + void heal(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 `@game2/game2.puml` around lines 1 - 59, Fix the PlantUML syntax and method signatures in the diagram. In the Hero class, correct the field initialization on line 8 from `- int hp 100` to `- int hp = 100` using the equals sign. Remove the trailing plus signs and add return types for methods: change `+ run()+` in SuperHero to `+ void run()`, change `+heal()+` in GreatWizard to `+ void heal()`, and change `+superHeal()` in GreatWizard to `+ void superHeal(Hero)` to include the parameter. In the Wizard class, add complete method signatures: change `+ setWand()` to `+ void setWand(Wand)` and change `+ heal()` to `+ void heal(Hero)` to include parameters and return types. In the Slime class, clarify the attack method signature from `+attack()` to `+ void attack(Hero)`.game2/src/main/java/com/survivalcoding/SuperHero.java (1)
4-9: ⚡ Quick win
SuperHero엔티티 내부의main실행 코드는 분리하는 편이 안전합니다.Line [4]~Line [9]의 데모 실행 코드는 클래스 책임을 흐리고, 이후 실수로 운영 코드에 남기기 쉽습니다.
main은 별도 실행용 클래스(예:App)나 테스트로 이동하는 것을 권장합니다.🤖 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 `@game2/src/main/java/com/survivalcoding/SuperHero.java` around lines 4 - 9, The main method containing demo execution code should be removed from the SuperHero entity class to maintain single responsibility principle and reduce the risk of test/demo code leaking into production. Move the entire main method (which creates a SuperHero instance with "홍길동" and 50 as parameters, then calls attack(), run(), and setFlying(true)) to a separate execution class such as App or to a test class. Remove the main method entirely from the SuperHero class.
🤖 Prompt for all review comments with 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.
Inline comments:
In `@game2/src/main/java/com/survivalcoding/GreatWizard.java`:
- Around line 14-16: The setMp method in the GreatWizard class is not validating
that the mp parameter is non-negative, which violates the contract established
by the parent class Wizard.setMp(). To fix this, add the same negative value
validation in GreatWizard.setMp() that exists in the parent Wizard class - check
if mp is less than zero and throw an appropriate exception (such as
IllegalArgumentException) with a descriptive message, or alternatively call the
parent class's setMp method to leverage its existing validation logic. This
ensures type substitution safety and maintains consistent precondition
enforcement across the inheritance hierarchy.
In `@game2/src/main/java/com/survivalcoding/Hero.java`:
- Around line 30-33: The Hero constructor in the parameterized constructor
(lines 30-33) directly assigns hp with `this.hp = hp;` which bypasses the
validation logic in the setHp() method (lines 17-21) that prevents negative
values. Replace the direct assignment `this.hp = hp;` with a call to `setHp(hp)`
to ensure the same HP validation invariant is enforced during object
construction as well as when updating the value later.
In `@game2/src/main/java/com/survivalcoding/Wizard.java`:
- Line 41: The exception message in the Wizard class at line 41 uses incorrect
terminology. The message says "3문장 이상" (3 sentences or more) but the actual
validation rule checks for 3 characters using name.length() < 3. Update the
error message string to use "3문자" (3 characters) instead of "3문장" (3 sentences)
to match the actual validation logic and provide accurate feedback to users and
tests.
---
Nitpick comments:
In `@game2/game2.puml`:
- Around line 1-59: Fix the PlantUML syntax and method signatures in the
diagram. In the Hero class, correct the field initialization on line 8 from `-
int hp 100` to `- int hp = 100` using the equals sign. Remove the trailing plus
signs and add return types for methods: change `+ run()+` in SuperHero to `+
void run()`, change `+heal()+` in GreatWizard to `+ void heal()`, and change
`+superHeal()` in GreatWizard to `+ void superHeal(Hero)` to include the
parameter. In the Wizard class, add complete method signatures: change `+
setWand()` to `+ void setWand(Wand)` and change `+ heal()` to `+ void
heal(Hero)` to include parameters and return types. In the Slime class, clarify
the attack method signature from `+attack()` to `+ void attack(Hero)`.
In `@game2/src/main/java/com/survivalcoding/Person.java`:
- Line 4: The `age` field in the Person class needs to restore encapsulation and
data consistency. Either restore the `final` modifier to `age` and ensure it is
only set in the constructor, or change `age` to `private` and modify the
`getAge()` method to return the calculated value `2026 - birthYear` instead of
storing it as a mutable field. If `setBirthYear()` exists or is added, ensure it
recalculates `age` based on the new `birthYear` value to maintain consistency.
This prevents external code or other parts of the class from breaking the
invariant relationship between `birthYear` and `age`.
In `@game2/src/main/java/com/survivalcoding/SuperHero.java`:
- Around line 4-9: The main method containing demo execution code should be
removed from the SuperHero entity class to maintain single responsibility
principle and reduce the risk of test/demo code leaking into production. Move
the entire main method (which creates a SuperHero instance with "홍길동" and 50 as
parameters, then calls attack(), run(), and setFlying(true)) to a separate
execution class such as App or to a test class. Remove the main method entirely
from the SuperHero class.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f1699240-a666-46ba-b131-66fad08109ad
📒 Files selected for processing (17)
TIL/2026-06-10-캡슐화, 컬렉션.mdTIL/2026-06-11-상속.mdgame2/game2.pumlgame2/src/main/java/com/survivalcoding/260615_연습문제1game2/src/main/java/com/survivalcoding/260616_연습문제game2/src/main/java/com/survivalcoding/GreatWizard.javagame2/src/main/java/com/survivalcoding/Hero.javagame2/src/main/java/com/survivalcoding/ListExam.javagame2/src/main/java/com/survivalcoding/Person.javagame2/src/main/java/com/survivalcoding/PoisonSlime.javagame2/src/main/java/com/survivalcoding/Slime.javagame2/src/main/java/com/survivalcoding/SuperHero.javagame2/src/main/java/com/survivalcoding/Wizard.javagame2/src/test/java/com/survivalcoding/GreatWizardTest.javagame2/src/test/java/com/survivalcoding/HeroTest.javagame2/src/test/java/com/survivalcoding/PoisonSlimeTest.javagame2/src/test/java/com/survivalcoding/WizardTest.java
💤 Files with no reviewable changes (2)
- game2/src/test/java/com/survivalcoding/HeroTest.java
- game2/src/main/java/com/survivalcoding/ListExam.java
| public void setMp(int mp) { | ||
| Mp = mp; | ||
| } |
There was a problem hiding this comment.
setMp 오버라이드가 상위 클래스의 음수 MP 방어 계약을 깨고 있습니다.
Line 14-16은 음수 MP를 그대로 허용합니다. Wizard.setMp()는 음수 입력을 예외 처리하므로, 하위 클래스도 동일 제약을 유지해야 타입 대체가 안전합니다.
제안 수정안
`@Override`
public void setMp(int mp) {
- Mp = mp;
+ if (mp < 0) {
+ throw new IllegalArgumentException("마법사의 MP는 0 이상이여야 한다");
+ }
+ Mp = mp;
}📝 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.
| public void setMp(int mp) { | |
| Mp = mp; | |
| } | |
| public void setMp(int mp) { | |
| if (mp < 0) { | |
| throw new IllegalArgumentException("마법사의 MP는 0 이상이여야 한다"); | |
| } | |
| Mp = mp; | |
| } |
🤖 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 `@game2/src/main/java/com/survivalcoding/GreatWizard.java` around lines 14 -
16, The setMp method in the GreatWizard class is not validating that the mp
parameter is non-negative, which violates the contract established by the parent
class Wizard.setMp(). To fix this, add the same negative value validation in
GreatWizard.setMp() that exists in the parent Wizard class - check if mp is less
than zero and throw an appropriate exception (such as IllegalArgumentException)
with a descriptive message, or alternatively call the parent class's setMp
method to leverage its existing validation logic. This ensures type substitution
safety and maintains consistent precondition enforcement across the inheritance
hierarchy.
| public Hero(String name, int hp) { | ||
| this.name = name; | ||
| this.hp = hp; | ||
| } |
There was a problem hiding this comment.
인자 생성자가 HP 음수 클램프 계약을 우회합니다.
Line 30-33에서 this.hp = hp;로 직접 대입하면, setHp()가 보장하는 음수 방어(Line 17-21)가 적용되지 않아 객체가 음수 HP로 생성될 수 있습니다. 생성 시점에도 동일한 불변식을 유지하도록 setter를 사용하세요.
제안 수정안
public Hero(String name, int hp) {
this.name = name;
- this.hp = hp;
+ setHp(hp);
}🤖 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 `@game2/src/main/java/com/survivalcoding/Hero.java` around lines 30 - 33, The
Hero constructor in the parameterized constructor (lines 30-33) directly assigns
hp with `this.hp = hp;` which bypasses the validation logic in the setHp()
method (lines 17-21) that prevents negative values. Replace the direct
assignment `this.hp = hp;` with a call to `setHp(hp)` to ensure the same HP
validation invariant is enforced during object construction as well as when
updating the value later.
| } | ||
| if (name.length() < 3) { | ||
| throw new IllegalArgumentException("이름이 3단어 이상이여야 함"); | ||
| throw new IllegalArgumentException("이름이 3문장 이상이여야 함"); |
There was a problem hiding this comment.
예외 메시지 용어가 검증 규칙과 다릅니다(문장 → 문자).
Line 41의 "이름이 3문장 이상이여야 함"은 실제 검증(name.length() < 3) 의미와 어긋납니다. 사용자/테스트 가독성을 위해 "3문자"로 맞추는 편이 좋습니다.
🤖 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 `@game2/src/main/java/com/survivalcoding/Wizard.java` at line 41, The exception
message in the Wizard class at line 41 uses incorrect terminology. The message
says "3문장 이상" (3 sentences or more) but the actual validation rule checks for 3
characters using name.length() < 3. Update the error message string to use "3문자"
(3 characters) instead of "3문장" (3 sentences) to match the actual validation
logic and provide accurate feedback to users and tests.
260616_02_김선진
📝 과제 정보
상속
📷 실행 결과 (또는 테스트 결과)
❓질문 및 어려웠던 점
🔄 자체 평가 & 회고