사이먼's 코딩노트
[Java] 문제풀이(2) 본문
- 심화된 Java 문제를 풀어봅시다.
- Main 메서드에 작성된 코드를 보고 나머지 클래스와 메서드를 작성해봅시다.
[문제 1]
- 주어진 코드에서 병사가 진급하는 기능과 진급 시 공격력이 증가하게 되도록 코드를 완성해봅시다.
public class Main {
public static void main(String[] args) {
병사 a병사 = new 병사();
a병사.이름 = "홍길동";
a병사.자기소개();
// 안녕하세요. 저는 홍길동 이병 입니다.
a병사.공격();
// 홍길동 이병이 공격합니다.(공격력 : 7)
a병사.진급();
a병사.자기소개();
// 안녕하세요. 저는 홍길동 일병 입니다.
a병사.공격();
// 홍길동 일병이 공격합니다.(공격력 : 9)
a병사.진급();
a병사.자기소개();
// 안녕하세요. 저는 홍길동 상병 입니다.
a병사.공격();
// 홍길동 상병이 공격합니다.(공격력 : 11)
}
}
[문제 1 정답]
- 아래 코드는 전체 코드가 길어져 Main 메서드를 제외한 클래스와 메서드만을 작성하였습니다.
class 병사 {
String 이름;
int 계급번호;
병사() {
계급번호 = 1;
}
String get계급() {
if(계급번호 == 1) {
return "이병";
}
else if(계급번호 == 2) {
return "일병";
}
else if(계급번호 == 3) {
return "상병";
}
else {
return null;
}
}
int get공격력() {
if(계급번호 == 1) {
return 7;
}
else if(계급번호 == 2) {
return 9;
}
else if(계급번호 == 3) {
return 11;
}
else {
return 0;
}
}
void 자기소개() {
System.out.printf("안녕하세요. 저는 %s %s 입니다.\n", 이름, get계급());
}
void 공격() {
System.out.printf("%s %s이 공격합니다. (공격력 : %d)\n", 이름, get계급(), get공격력());
}
void 진급() {
계급번호++;
}
}
- Main 메서드를 살펴보면 a병사의 이름을 홍길동으로 저장을 해놨기 때문에 우선 병사 클래스를 만들어 String 타입의 이름 변수를 선언해준다.
- 메서드는 총 3가지가 필요하다. 자기소개() 메서드는 이름과 계급을 나타내고, 공격() 메서드는 이름과 계급과 공격력을 나타내고, 진급() 메서드는 이병에서 일병, 일병에서 상병으로 계급이 한 단계씩 올라간다는 것을 알 수 있다.
- 먼저 계급번호라는 변수를 만들어 병사 생성자를 통해 계급번호를 최초에 1로 세팅해준다.
- 우리가 하려는 작업은 계급번호가 1이면 계급은 이병이고 공격력은 7, 2이면 계급은 일병이고 공격력은 9, 3이면 계급은 상병이고 공격력은 11이 되도록하고 진급() 메서드를 통해서 계급번호를 하나씩 증가시켜주는 코드를 구현해보려한다.
- 우선 진급() 메서드에서는 해당 메서드가 호출될 때 마다 번호가 증가하도록 계급번호++를 작성해준다.
- 그리고 직접 메서드에서 각 계급과 공격력을 return 받기 위해 get계급() 과 get공격력() 메서드를 추가로 작성한다.
- get계급() 메서드는 문자열을 리턴하기 때문에 타입은 String으로 하고 조건문을 사용하여 각 계급번호에 맞는 계급을 return한다.
- get공격력() 메서드는 정수를 리턴하기 때문에 타입은 int로 하고 조건문을 사용하여 각 계급번호에 맞는 공격력을 return한다.
- 마지막으로 각 출력문에서 서식지정자에 맞게 이름과 메서드를 호출해준다.
[문제 2]
- 주어진 코드에서 전사의 무기변경 메서드를 추가하고, 각 무기마다 데미지를 나타내도록 코드를 완성해봅시다.
public class Main {
public static void main(String[] args) {
전사 a전사 = new 전사();
a전사.공격();
// 칼(으)로 공격합니다.
// 데미지 : 78
a전사.창_모드로_변경();
a전사.공격();
// 창(으)로 공격합니다.
// 데미지 : 80
a전사.지팡이_모드로_변경();
a전사.공격();
// 지팡이(으)로 공격합니다.
// 데미지 : 12
}
}
[문제 2 정답]
- 아래 코드는 전체 코드가 길어져 Main 메서드를 제외한 클래스와 메서드만을 작성하였습니다.
class 전사 {
무기 a무기;
전사() {
a무기 = new 칼();
}
void 공격() {
a무기.작동();
}
void 창_모드로_변경() {
a무기 = new 창();
}
void 지팡이_모드로_변경() {
a무기 = new 지팡이();
}
}
class 무기 {
String 무기명;
int 데미지;
void 작동() {
System.out.printf("%s(으)로 공격합니다.\n", 무기명);
System.out.printf("데미지 : %d\n", 데미지);
}
}
class 칼 extends 무기 {
칼() {
무기명 = "칼";
데미지 = 78;
}
}
class 창 extends 무기 {
창() {
무기명 = "창";
데미지 = 80;
}
}
class 지팡이 extends 무기 {
지팡이() {
무기명 = "지팡이";
데미지 = 12;
}
}
- Main 메서드를 살펴보면 공격() 메서드를 통해 전사가 어떤 무기로 공격하고 해당 무기의 공격력을 출력하도록 한다.
- 최초의 전사는 칼이라는 무기를 가지고 있고 창_모드로_변경() 과 지팡이_모드로_변경() 메서드를 통해 무기의 타입을 변경하는 것을 알 수 있다.
- 먼저 모든 무기를 포용할 수 있는 무기 클래스를 생성하고 해당 클래스를 상속받는 칼, 창, 지팡이 클래스를 생성한다.
- 전사 클래스에선 a무기라는 인스턴스 변수를 생성하고 생성자를 통해 최초에 전사가 칼 객체를 생성할 수 있도록 한다.
- 그리고 모드변경 메서드에서는 변경하고 싶은 무기 클래스의 객체를 생성할 수 있도록 코드를 작성한다.
- 전사 클래스에 생성된 공격() 메서드는 무기별로 공격이 가능하도록 작동() 이라는 메서드를 무기 클래스에서 호출한다.
- 공격() 메서드에서 직접 출력문을 작성해도 되지만 위와 같이 하는 이유는 나중에 수많은 전사와 더 많은 종류의 무기가 생겼을 때 일일이 출력문을 하나씩 수정해야되는 번거로움이 있기 때문에 해당 작업을 최소화하기 위해서 작동() 이라는 메서드를 호출하는 것이다.
- 무기 클래스의 작동() 메서드는 출력문을 작성하고 각 출력문은 서식지정자를 통해 무기명과 데미지를 불러온다.
- 이 때 무기명과 데미지는 선언되지 않은 변수이기 떄문에 무기 클래스에 각 타입에 맞춰 선언해주고 칼, 창, 지팡이 클래스에서 각 변수를 생성자를 통해 세팅해준다.
- 그러면 각 무기 종류별로 무기명과 데미지가 지정되어 있어 우리가 원하는 출력문을 출력할 수 있다.
[문제 3]
- 주어진 코드에서 전사 클래스의 중복을 최소화하도록 코드를 완성해봅시다.
public class Main {
public static void main(String[] args) {
전사타입A a전사타입A = new 전사타입A();
a전사타입A.공격();
전사타입B a전사타입B = new 전사타입B();
a전사타입B.공격();
전사타입C a전사타입C = new 전사타입C();
a전사타입C.공격();
전사타입D a전사타입D = new 전사타입D();
a전사타입D.공격();
}
}
abstract class 전사 {
abstract void 공격();
}
class 전사타입A extends 전사 {
void 공격() {
System.out.println("칼로 공격");
}
}
class 전사타입B extends 전사 {
void 공격() {
System.out.println("칼로 공격");
}
}
class 전사타입C extends 전사 {
void 공격() {
System.out.println("활로 공격");
}
}
class 전사타입D extends 전사 {
void 공격() {
System.out.println("활로 공격");
}
}
[문제 3 정답]
- 아래 코드는 전체 코드가 길어져 Main 메서드를 제외한 클래스와 메서드만을 작성하였습니다.
- Main 메서드는 수정된 곳이 없다는 점을 참고해주세요.
class 전사 {
무기 a무기;
void 공격() {
a무기.작동();
}
}
class 전사타입A extends 전사 {
전사타입A() {
a무기 = new 칼();
}
}
class 전사타입B extends 전사 {
전사타입B() {
a무기 = new 칼();
}
}
class 전사타입C extends 전사 {
전사타입C() {
a무기 = new 활();
}
}
class 전사타입D extends 전사 {
전사타입D() {
a무기 = new 활();
}
}
abstract class 무기 {
abstract void 작동();
}
class 칼 extends 무기 {
void 작동() {
System.out.println("칼로 공격");
}
}
class 활 extends 무기 {
void 작동() {
System.out.println("활로 공격");
}
}
- 위 문제의 목적은 전사가 생성될 때마다 공격() 메서드를 호출하여 출력문을 사용하여 출력문에 수정이 필요할 때 마다 모든 출력문을 일일이 수정해야되는 번거로움을 방지하기 위함이다.
- 먼저 모든 무기를 포용할 수 있는 무기 클래스를 생성하고 해당 클래스를 상속받는 칼과 활 클래스를 생성한다.
- 전사 클래스는 abstract를 해제하고 a무기라는 인스턴스 변수를 생성하고 공격() 메서드에서는 무기별로 공격이 가능하도록 작동() 이라는 메서드를 호출한다.
- 문제에서 전사타입A와 전사타입B 객체 변수는 무기로 칼을 가지고, 전사타입C와 전사타입D 객체 변수는 무기로 활을 가진다.
- 기존에 각 클래스에서 공격() 메서드를 통한 출력문은 모두 삭제하고 각 전사타입 변수별로 무기에 맞는 객체를 생성해준다.
- 마지막으로 칼과 활 클래스의 작동() 메서드에 출력문을 작성해준다.
반응형
'Java > Java' 카테고리의 다른 글
[Java] super / final / switch (0) | 2024.03.12 |
---|---|
[Java] 생성자 문제풀이 (0) | 2024.03.12 |
[Java] 문제풀이(1) (0) | 2024.03.11 |
[Java] ArrayList (0) | 2024.02.19 |
[Java] 종합 문제풀이 (0) | 2024.02.19 |