Java] OOP Training

Object-oriented Programming, 객체 지향 프로그래밍

먼저, 궁금했던 점에 대해서 기재

  1. 출력문에서 5/3이면 int형으로 나오는지, double형으로 나오는지
1
2
3
4
5
6
7
System.out.println(5/3); //1
System.out.println(((Object) (5/3)).getClass().getTypeName()); //java.lang.Integer
int res = 5/3;
System.out.println(res); //1

double res = 5/3;
System.out.println(res); //1.0

예상으로는 자동형변환이 이뤄져서 double 타입이 나올거라고 생각하였지만, int형이 나왔다.

double형으로 선언을 하여도 받아오는 값은 1.0이었다.

소수점이 계산된 값을 가져오기 위해서는 처음부터 숫자를 소수로 주어지거나 형변환을 명시적으로 주어 처리해야한다.

1
2
System.out.println((double)5/3); //1.6666666666666667
System.out.println(5.0/3); //1.6666666666666667
  1. 반올림 방법

그렇다면 반올림은 Math.round()을 통해 하면 될텐데, 2째 자리까지 보여지게 하려면 어떻게 해야할까?

1
2
3
4
System.out.println(Math.round(5.0/3*100)/100.0); //1.67

// 이해를 돕기위해 소수점 셋째자리까지
System.out.println(Math.round(5.0/3*1000)/1000.0); //1.667

위와 같이 보여질 자리수만큼 곱해주었다가 나눠주면 된다.

Problem 01.

다음은 컴퓨터 게임의 병사(marine)를 클래스로 정의한 것이다. 이 클래스의 멤버 중에 static을 붙여야 하는 것은 어떤 것들이고 그 이유는 무엇인가? (단, 모든 병사의 공격력과 방어력은 같아야 한다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Marine {
int x = 0, y = 0; //위치 좌표(x,y)
int hp = 60; //현재 체력
int weapon = 6; //공격력
int armor = 0; //방어력

void weaponUp() {
weapon++;
}
void armorUp() {
armor++;
}
void move(int x, int y) {
this.x = x;
this.y = y;
}
}

모든 병사의 공격력과 방어력은 같다고 하였기에 인스턴스 변수가 아닌 static으로 선언해준다. 인스턴스 변수일 경우에는 각 객체마다 가지고 있는 공격력과 방어력이 다를 수 있기에…

그리고 static변수로 바꿔준 공격력과 방어력 변수를 사용하는 Instance Method에 static Method로 변경해준다.

답안]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Marine {
int x = 0, y = 0; //위치 좌표(x,y)
int hp = 60; //현재 체력
static int weapon = 6; //공격력
static int armor = 0; //방어력

static void weaponUp() {
weapon++;
}
static void armorUp() {
armor++;
}
void move(int x, int y) {
this.x = x;
this.y = y;
}
}

Problem 02.

다음 중 생성자에 대한 설명으로 옳지 않은 것은? (모두 고르시오)

  1. 모든 생성자의 이름은 클래스의 이름과 동일해야한다.
  2. 생성자는 객체를 생성하기 위한 것이다.
  3. 클래스에는 생성자가 반드시 하나 이상 있어야 한다.
  4. 생성자가 없는 클래스는 컴파일러가 기본 생성자를 추가한다.
  5. 생성자는 오버로딩 할 수 없다.

생성자는 객체를 생성할 때 사용되기는 하지만, 객체를 초기화할 목적으로 사용된다.

객체를 생성하는 것은 new 연산자이다.

생성자는 오버로딩이 가능하여 하나의 클래스에 여러 개의 생성자를 정의할 수 있다.

답안] 2, 5

Problem 03.

다음 중 this에 대한 설명으로 맞지 않은 것은? (모두 고르시오)

  1. 객체 자신을 가리키는 참조변수이다.
  2. 클래스 내에서라면 어디서든 사용할 수 있다.
  3. 지역변수와 인스턴스변수를 구별할 때 사용한다.
  4. 클래스 메서드 내에서는 사용할 수 없다.

this는 클래스 멤버(static이 붙은 변수나 메소드)에는 사용할 수 없다.

답안] 2

Problem 04.

다음 중 오버로딩이 성립하기 위한 조건이 아닌 것은? (모두 고르시오)

  1. 메서드의 이름이 같아야 한다.
  2. 매개변수의 개수나 타입이 달라야 한다.
  3. 리턴타입이 달라야 한다.
  4. 매개변수의 이름이 달라야 한다.

오버라이딩의 조건

  1. 메서드 이름이 같아야 한다.

  2. 매개변수의 개수 또는 타입이 달라야 한다.

  3. 매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.

    (리턴타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.)

답안] 3, 4

Problem 05.

다음 중 아래의 add 메서드를 올바르게 오버로딩 한 것은? (모두 고르시오)

1
long add(int a, int b) { return a+b; }
  1. long add(int x, int y) { return x+y; }
  2. long add(long a, long b) { return a+b; }
  3. int add(byte a, byte b) { return a+b; }
  4. int add(long a, int b) { return (int)(a+b); }

오버라이딩의 조건

  1. 메서드 이름이 같아야 한다.

  2. 매개변수의 개수 또는 타입이 달라야 한다.

  3. 매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.

    (리턴타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.)

답안] 2, 3, 4

Problem 06.

다음 중 초기화에 대한 설명으로 옳지 않은 것은? (모두 고르시오)

  1. 멤버변수는 자동 초기화되므로 초기화하지 않고도 값을 참조할 수 있다.
  2. 지역변수는 사용하기 전에 반드시 초기화해야 한다.
  3. 초기화 블럭보다 생성자가 먼저 수행된다.
  4. 명시적 초기화를 제일 우선적으로 고려해야 한다.
  5. 클래스변수보다 인스턴스변수가 먼저 초기화된다.

클래스 변수는 클래스가 처음 메모리에 로딩될 때, 자동 초기화되므로 인스턴스 변수보다 먼저 초기화 된다. 그리고 생성자는 초기화 블럭이 수행된 다음에 수행된다.

답안] 3, 5

Problem 07.

다음중 인스턴스 변수의 초기화 순서가 올바른 것은?

  1. 기본값 - 명시적 초기화 - 초기화 블럭 - 생성자
  2. 기본값 - 명시적 초기화 - 생성자 - 초기화 블럭
  3. 기본값 - 초기화 블럭 - 명시적 초기화 - 생성자
  4. 기본값 - 초기화 블럭 - 생성자 - 명시적 초기화

클래스 변수의 초기화 시점 : 클래스가 처음 로딩될 때 단 한번 초기화 된다.

인스턴스 변수의 초기화 시점 : 인스턴스가 생성될 때마다 각 인스턴스별로 초기화가 이뤄진다.

클래스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭

인스턴스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자

답안] 1

Problem 08.

다음 중 지역변수에 대한 설명으로 옳지 않은 것은? (모두 고르시오)

  1. 자동 초기화되므로 별도의 초기화가 필요없다.
  2. 지역변수가 선언된 메서드가 종료되면 지역변수도 함께 소멸된다.
  3. 메서드의 매개변수로 선언된 변수도 지역변수이다.
  4. 클래스변수나 인스턴스변수보다 메모리 부담이 적다.
  5. 힙(heap)영역에 생성되며 가비지 컬렉터에 의해 소멸된다.

지역변수는 자동 초기화 되지 않기 때문에 사용하기 전에 반드시 적절한 값으로 초기화 해주어야한다. 지역변수는 자신이 선언된 블럭이나 메서드가 종료되면 소멸되므로 메모리 부담이 적다. 힙(heap) 영역에는 인스턴스(인스턴스 변수)가 생성되는 영역이며, 지역변수는 호출스택(call stack)에 생성된다.

답안] 1, 5

Problem 09.

호출스택이 다음과 같은 상황일 때 옳지 않은 설명은? (모두 고르시오)

[CallStack]
println
method1
method2
main
  1. 제일 먼저 호출스택에 저장된 것은 main메서드이다.
  2. println메서드를 제외한 나머지 메서드들은 모두 종료된 상태이다.
  3. method2메서드를 호출한 것은 main메서드이다.
  4. println메서드가 종료되면 method1메서드가 수행을 재개한다.
  5. main-method2-method1-println의 순서로 호출되었다.
  6. 현재 실행중인 메서드는 println뿐이다.

호출스택의 제일 위에 있는 메서드가 현재 수행중인 메서드이며, 호출스택 안의 나머지 메서드들은 대기상태이다.

답안] 2

Problem 10.

다음과 같이 정의된 메서드를 작성하고 테스트하시오.

메서드명 : shuffle

기능 : 주어진 배열에 담긴 값의 위치를 바꾸는 작업을 반복하여 뒤섞이게 한다. 처리한 배열을 반환한다.

반환타입 : int[]

매개변수 : int[] arr - 정수값이 담긴 배열

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Arrays;

public class Card {
/*
* shuffle 메서드를 작성하시오.
* */
public static void main(String[] args) {
int[] original = {1,2,3,4,5,6,7,8,9};
System.out.println(Arrays.toString(original));

int[] result = shuffle(original);
System.out.println(Arrays.toString(result));
}
}

답안]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Arrays;

public class Card {

static int[] shuffle(int[] arr) {
if(arr == null || arr.length == 0) { //유효성 체크
return arr;
}
for(int i=0; i<arr.length*2; i++) { //*2만큼 하면 충분히 섞이기에
int x = (int)(Math.random()*arr.length);
int y = (int)(Math.random()*arr.length);

int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
return arr;
}

public static void main(String[] args) {
int[] original = {1,2,3,4,5,6,7,8,9};
System.out.println(Arrays.toString(original));

int[] result = shuffle(original);
System.out.println(Arrays.toString(result));
}
}

Problem 11.

다음과 같이 정의된 메서드를 작성하고 테스트하시오.

메서드명 : isNumber

기능 : 주어진 문자열이 모두 숫자로만 이루어져 있는지 확인한다. 모두 숫자로만 이루어져 있으면 true 반환, 아니라면 false 반환

만일 주어진 문자열이 null이거나 빈문자열 ‘’이라면 false 반환

반환타입 : boolean

매개변수 : String str - 검사할 문자열

1
2
3
4
5
6
7
8
9
10
11
12
public class Test {

//isNumber 메서드를 작성하시오.

public static void main(String[] args) {
String str = "123";
System.out.println(str + "는 숫자입니까?" + isNumber(str));

str = "1234o";
System.out.println(str + "는 숫자입니까?" + isNumber(str));
}
}

답안]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test {
static boolean isNumber(String str) {
for(int i=0; i < str.length(); i++) {
if('0' <= str.charAt(i) && str.charAt(i) <= '9') {
continue;
} else {
return false;
}
}
return true;
}

public static void main(String[] args) {
String str = "123";
System.out.println(str + "는 숫자입니까?" + isNumber(str));

str = "1234o";
System.out.println(str + "는 숫자입니까?" + isNumber(str));
}
}