-
Notifications
You must be signed in to change notification settings - Fork 18
20260616_19_윤우상 #56
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
base: student/19_윤우상
Are you sure you want to change the base?
20260616_19_윤우상 #56
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| # 2026-06-16 상속 | ||
|
|
||
| ## 과제 피드백 | ||
|
|
||
| - `assertDoesNotThrow(() -> mainTestWand.setPower(setRandomDoubleInRange), "정상 값 입력시 예외발생하는 오류 발생");` 와 같은 | ||
| 랜덤값을 이용한 테스트는 지양하는것이 좋음. | ||
| - 말 그대로 랜덤값이다보니, 성공 실패가 갈릴 수 있음 | ||
| - 경계값 테스트로 전환하여 진행할 것 | ||
| - `@BeforeEach` 를 이용하여 매 테스트 실행 전에 준비작업 (`Wand testWand = new Wand();` 와 같은) 을 자동화 할 수 있음 | ||
| - 코드 리뷰나 협업할 때 편하도록 한 눈에 들어올 수 있게 코드 길이를 조절할 것 | ||
|
|
||
| --- | ||
|
|
||
| ## 상속 | ||
|
|
||
| - 이전에 만든 클래스와 비슷한 다른 클래스를 만들 필요가 있을 때 사용 | ||
|
|
||
| ### 상속의 기초 | ||
|
|
||
| - extends (클래스명)을 클래스 뒤에 붙여, 기존 (클래스명)을 기초로 하는 새로운 클래스 정의 가능 | ||
| - 부모클래스의 멤버는 자동적으로 자식클래스에 상속 | ||
| - 추가되는 부분만 기술하면 됨 | ||
| - 부모클래스에 있는 메서드를 자식클래스에서 작성하는 경우를 오버라이드한다고 함 | ||
| - final을 붙인 클래스는 상속 / 오버라이드 할 수 없다. | ||
| - is-a 를 충족해야 올바른 상속 | ||
| - 예시 | ||
| 1. 차는 탈 것의 한 종류다. (car is a vehicle) | ||
| 2. IPhone은 Phone의 한 종류다. | ||
| - 상속에는 추상적 / 구체적 관계에 있다는 것을 정의하는 역할도 가짐 | ||
|
|
||
| #### 오버라이드 | ||
|
|
||
| - 부모 클래스에서 받은 메서드를 자식클래스에 맞게 수정하는 것 | ||
| - Slime에서의 attack()은 hero의 체력을 10 깍는 함수지만 <br>PoisonSlime의 attack()은 체력을 10 깎음과 동시에 독데미지로 현재 체력의 1/5 만큼 추가로 깍음 | ||
| - 코드 예시 | ||
| ```java | ||
| // Slime 에서의 attack() | ||
| public void attack(Hero hero) { | ||
| if (hero == null) { | ||
| throw new IllegalArgumentException("공격하는 대상이 있어야합니다."); | ||
| } | ||
|
|
||
| System.out.println("슬라임 " + this.suffix + "이/가 공격했다"); | ||
| System.out.println("대상 " + hero.getName() + "에게 " + slimeAttackPoint + "포인트 데미지!"); | ||
|
|
||
| hero.setHP(hero.getHP() - slimeAttackPoint); | ||
| } | ||
|
|
||
| // PoisonSlime 에서의 attack() | ||
| @Override | ||
| public void attack(Hero hero) { | ||
| super.attack(hero); | ||
| if (poisonCount > 0) { | ||
| System.out.println("포이즌슬라임" + this.getSuffix() + "의 능력! 추가로, 독 포자를 살포했다!"); | ||
| System.out.println("대상 " + hero.getName() + "에게 " + hero.getHP() / 5 + "포인트 독 데미지!"); | ||
| hero.setHP(hero.getHP() * 4 / 5); | ||
| poisonCount -= 1; | ||
| } else { | ||
| System.out.println("포이즌슬라임" + this.getSuffix() + "은 독을 모두 소모했다."); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### 인스턴스 | ||
|
|
||
| - 내부에 부모클래스의 인스턴스를 가지는 다중구조를 가짐 | ||
| - 보다 바깥의 인스턴스에 속하는 자식클래스의 오버라이드한 메서드부터 동작 | ||
| - 오버라이드 한 메서드 -> 자식 클래스의 메서드 -> 부모클래스의 메서드 순으로 검색하여 실행 | ||
| - 단, 생성자의 경우에는 부모 먼저 실행하고, 자식의 생성자가 실행함 | ||
| - 부모 클래스인 Hero에 있는 생성자가 자식클래스인 SuperHero에 있는 생성자보다 먼저 동작 | ||
| - 외측의 인스턴스에 속하는 메서드는 super를 사용하여 내측 인스턴스의 멤버에 접근 가능 | ||
|
|
||
| ### 생성자 동작 | ||
|
|
||
| - 다중 구조의 인스턴스가 생성되는데, JVM은 자동으로 가장 외측 인스턴스의 생성자를 호출함. | ||
| - 모든 생성자는 부모 인스턴스의 생성자를 호출 할 필요가 있음 | ||
| - 생성자 선두에 `super()`가 없어도 암묵적으로 `super();` 가 추가됨 | ||
|
|
||
| ## UML | ||
|
|
||
| - 아래와 같이 PlantUML을 이용하여 구성도를 그릴 수 있음 | ||
| - 정보를 주고받을 때 용이함 | ||
|
|
||
| ```plantuml | ||
| @startuml | ||
|
|
||
| scale 2 | ||
|
|
||
| class SuperHero extends Hero { | ||
| +void setFlying(boolean Flying) | ||
| +void boolean isFlying() | ||
| } | ||
|
|
||
| class Hero | ||
| { | ||
| - int hp | ||
|
|
||
| + void attack() | ||
| } | ||
|
|
||
| @enduml | ||
| ``` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| @startuml | ||
|
|
||
| scale 2 | ||
|
|
||
| class SuperHero extends Hero { | ||
| - boolean isFlying | ||
|
|
||
| + SuperHero(String name, int hp) | ||
| + SuperHero(String name) | ||
| + SuperHero() | ||
|
|
||
| + void setFlying(boolean Flying) | ||
| + boolean isFlying() | ||
| + void run() | ||
| } | ||
|
|
||
| class Hero | ||
| { | ||
| - int hp | ||
| - int maxHP | ||
| - String name | ||
|
|
||
| + String getName() | ||
| + int getHP() | ||
| + int getMaxHP() | ||
| + void setName(String name) | ||
| + void setHP(int hp) | ||
| + void setMaxHP(int maxHP) | ||
|
|
||
| + void attack() | ||
| + void run() | ||
| + void slip() | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
|
|
||
| class Wizard | ||
| { | ||
| - String name | ||
| - int hp | ||
| - int mp | ||
| - Wand wand | ||
|
|
||
| + int defaultWizardMP = 100 | ||
|
|
||
| + {Constructor} Wizard(String name, int hp, int mp, Wand wand) | ||
| + {Constructor} Wizard(String name, int hp, int mp) | ||
| + {Constructor} Wizard(String name, int hp) | ||
| + {Constructor} Wizard(String name) | ||
|
|
||
| + String getName() | ||
| + void setName(String name) | ||
| + int getHP() | ||
| + void setHP(int hp) | ||
| + int getMP() | ||
| + void setMP(int mp) | ||
| + Wand getWand() | ||
| + void setWand(Wand wand) | ||
|
|
||
| + void heal(Hero hero) | ||
| } | ||
|
|
||
| class GreatWizard extends Wizard | ||
| { | ||
| + int defaultGreatWizardMP = 150 | ||
| + int recoverPoint = 25 | ||
|
|
||
| + {Constructor} GreatWizard(String name, int hp, int mp, Wand wand) | ||
| + {Constructor} GreatWizard(String name, int hp, int mp) | ||
| + {Constructor} GreatWizard(String name, int hp) | ||
| + {Constructor} GreatWizard(String name) | ||
|
|
||
| + heal(Hero hero) | ||
| + superHeal(Hero hero) | ||
| } | ||
|
|
||
| class Slime | ||
| { | ||
| ~ int slimeAttackPoint | ||
| - String suffix | ||
| - int hp | ||
| - int maxHP | ||
|
|
||
| + {Constructor} Slime(String suffix, int hp) | ||
|
|
||
| + String getSuffix() | ||
| + int getHP() | ||
| + int getMaxHP() | ||
|
|
||
| + void setSuffix(String suffix) | ||
| + void setHP(int hp) | ||
| + void setMaxHP(int MaxHP) | ||
| } | ||
|
|
||
| class PoisonSlime extends Slime | ||
| { | ||
| - int poisonCount = 5 | ||
|
|
||
| + {Constructor} PoisonSlime(String suffix, int hp) | ||
|
|
||
| + int getPoisonCount() | ||
| + void attack(Hero hero) | ||
| } | ||
|
|
||
| class Cleric | ||
| { | ||
| ~ int maxHP | ||
| ~ int maxMP | ||
| ~ int selfAidMPCost = 5 | ||
| ~ int randBoundary = 3 | ||
| ~ Random rand | ||
|
|
||
| - String name | ||
| - int hp | ||
| - int mp | ||
|
|
||
| + {Constructor} Cleric(String name, int hp, int mp) | ||
| + {Constructor} Cleric(String name, int hp) | ||
| + {Constructor} Cleric(String name) | ||
|
|
||
| + int getSelfAidMPCost() | ||
| + String getName() | ||
| + int getHP() | ||
| + int getMP() | ||
|
|
||
| + void setName(String name) | ||
| + void setHP(int hp) | ||
| + void setMP(int mp) | ||
|
|
||
| + void selfAid() | ||
| + int pray(int second) | ||
|
|
||
| } | ||
|
|
||
| @enduml | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,19 +9,14 @@ public class Cleric { | |
| final int randBoundary = 3; | ||
| final Random rand = new Random(); | ||
|
|
||
| String name; | ||
| int hp; | ||
| int mp; | ||
| private String name; | ||
| private int hp; | ||
| private int mp; | ||
|
|
||
| Cleric(String name, int hp, int mp) { | ||
| if (hp <= 0 || hp > 50) { | ||
| throw new IllegalArgumentException("HP는 최소 1, 최대 50이어야 합니다."); | ||
| } else if (mp < 0 || mp > 10) { | ||
| throw new IllegalArgumentException("MP는 최대 10이여야 합니다. 음수는 입력할 수 없습니다."); | ||
| } | ||
| this.name = name; | ||
| this.hp = hp; | ||
| this.mp = mp; | ||
| this.setName(name); | ||
| this.setHP(hp); | ||
| this.setMP(mp); | ||
| } | ||
|
|
||
| Cleric(String name, int hp) { | ||
|
|
@@ -32,17 +27,45 @@ public class Cleric { | |
| this(name, maxHP, maxMP); | ||
| } | ||
|
|
||
| Cleric() { | ||
| throw new IllegalArgumentException("스탯을 입력하지 않은 클레릭은 생성될 수 없습니다."); | ||
|
|
||
| public int getSelfAidMPCost() { | ||
| return selfAidMPCost; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public void setName(String name) { | ||
| if (name == null) { | ||
| throw new IllegalArgumentException("이름은 null값 일 수 없습니다."); | ||
| } | ||
| this.name = name; | ||
| } | ||
|
|
||
| public int getHP() { | ||
| return hp; | ||
| } | ||
|
|
||
| public void setHP(int hp) { | ||
| this.hp = Math.clamp(hp, 0, maxHP); | ||
| } | ||
|
|
||
| public int getMP() { | ||
| return mp; | ||
| } | ||
|
|
||
| public void setMP(int mp) { | ||
| this.mp = Math.clamp(mp, 0, maxMP); | ||
|
Comment on lines
+50
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== Potential Java toolchain files =="
fd -HI 'pom.xml|build.gradle|build.gradle.kts|gradle.properties|settings.gradle|mvnw|.tool-versions|.java-version|.sdkmanrc' | sort
echo
echo "== Java version declarations =="
TOOLCHAIN_FILES="$(fd -HI 'pom.xml|build.gradle|build.gradle.kts|gradle.properties|settings.gradle|.tool-versions|.java-version|.sdkmanrc' || true)"
if [ -n "${TOOLCHAIN_FILES}" ]; then
rg -n --no-heading 'sourceCompatibility|targetCompatibility|toolchain|languageVersion|maven.compiler.source|maven.compiler.target|<release>|java.version|--release' ${TOOLCHAIN_FILES} || true
else
echo "No toolchain declaration files found."
fi
echo
echo "== Math.clamp usage sites =="
rg -n --no-heading 'Math\.clamp\s*\('Repository: SurvivalCodingCampus/polytech_java2 Length of output: 541 🏁 Script executed: #!/bin/bash
echo "=== game/build.gradle ==="
cat game/build.gradle
echo -e "\n=== root build.gradle ==="
cat build.gradle
echo -e "\n=== settings.gradle ==="
cat settings.gradleRepository: SurvivalCodingCampus/polytech_java2 Length of output: 931 🏁 Script executed: #!/bin/bash
echo "=== Checking for gradle.properties ==="
if [ -f gradle.properties ]; then
cat gradle.properties
else
echo "No gradle.properties found"
fi
echo -e "\n=== Checking for JAVA_HOME or java version in system ==="
which java && java -version 2>&1 || echo "Java not available in sandbox"
echo -e "\n=== Double-checking all Math.clamp usages with context ==="
rg -B 2 -A 2 'Math\.clamp\s*\(' game/src/Repository: SurvivalCodingCampus/polytech_java2 Length of output: 1412
현재
현재 Math.clamp 사용 위치🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| void selfAid() { | ||
| // 5 미만일 때 실패하는 로직 구현 | ||
| if (mp < selfAidMPCost) { | ||
| if (this.getMP() < selfAidMPCost) { | ||
| System.out.println("MP가 부족합니다."); | ||
| return; | ||
| } | ||
| mp -= selfAidMPCost; | ||
| this.setMP(this.getMP() - selfAidMPCost); | ||
| hp = maxHP; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /* | ||
| 연습문제 5. | ||
| GreatWizard 클래스 요구사항: | ||
| Wizard 클래스를 상속받음 | ||
| 필드: | ||
| mp의 초기값은 150 | ||
| 메서드: | ||
| void heal(Hero hero) 재정의 : hp를 25 회복시키고 자신의 mp를 5 소모 | ||
| void superHeal(Hero hero) : hp를 최대로 회복시키고 자신의 mp를 50 소모 | ||
| mp가 부족하면 "마나가 부족합니다" 출력 | ||
| 힐을 성공하면 "슈퍼 힐을 시전했습니다. 대상 HP: XX" 출력 | ||
| */ | ||
|
|
||
| package com.survivalcoding; | ||
|
|
||
| public class GreatWizard extends Wizard { | ||
| public static final int defaultGreatWizardMP = 150; | ||
| public static int recoverPoint = 25; | ||
| public static final int healMPCost = 5; | ||
| public static final int superHealMPCost = 50; | ||
|
|
||
|
|
||
| public GreatWizard(String name, int hp, int mp, Wand wand) { | ||
| super(name, hp, mp, wand); | ||
| } | ||
|
|
||
| public GreatWizard(String name, int hp, int mp) { | ||
| super(name, hp, mp); | ||
| } | ||
|
|
||
| public GreatWizard(String name, int hp) { | ||
| super(name, hp, defaultGreatWizardMP); | ||
| } | ||
|
|
||
| public GreatWizard(String name) { | ||
| super(name, Wizard.defaultWizardHP, defaultGreatWizardMP); | ||
| } | ||
|
|
||
| @Override | ||
| public void heal(Hero hero) { | ||
| if (hero == null) { | ||
| throw new IllegalArgumentException("Hero는 null 값이 올 수 없습니다."); | ||
| } | ||
| if (this.getMP() >= healMPCost) { | ||
| hero.setHP(hero.getHP() + recoverPoint); | ||
| System.out.println("힐을 시전했습니다. " + hero.getName() + " HP : " + hero.getHP()); | ||
| this.setMP(this.getMP() - healMPCost); | ||
| } else { | ||
| System.out.println("마나가 부족합니다."); | ||
| } | ||
| } | ||
|
|
||
| public void superHeal(Hero hero) { | ||
| if (hero == null) { | ||
| throw new IllegalArgumentException("Hero는 null 값이 올 수 없습니다."); | ||
| } | ||
| if (this.getMP() >= superHealMPCost) { | ||
| this.setMP(this.getMP() - superHealMPCost); | ||
| hero.setHP(hero.getMaxHP()); | ||
| System.out.println("슈퍼 힐을 시전했습니다. " + hero.getName() + " HP : " + hero.getHP()); | ||
| } else { | ||
| System.out.println("마나가 부족합니다."); | ||
| } | ||
| } | ||
| } |
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.
UML 예시 메서드 시그니처 표기를 수정해 주세요.
Line 91의
+void boolean isFlying()는 반환형 표기가 잘못되었습니다.+boolean isFlying()로 고쳐야 예시가 올바른 형태가 됩니다.🤖 Prompt for AI Agents