본문 바로가기

Programming/Java의 정석

[Java의 정석 3판] 연습 문제 chapter6 객체지향1

[6-1] 다음과 같은 멤버변수를 갖는 SutdaCard클래스를 정의하시오.

	 class SutdaCard{
		 int num;
		 boolean isKwang;
	 }

 

[6-2] 문제6-1에서 정의한 SutdaCard클래스에 두 개의 생성자와 info()를 추가해서 실행결과와 같은 결과를 얻도록 하시오.

public class practice {

	public static void main(String[] args) {
	
		SutdaCard card1 = new SutdaCard(3, false);
		SutdaCard card2 = new SutdaCard();
	
		System.out.println(card1.info());
		System.out.println(card2.info());
	}
}
	class SutdaCard {
	
	int num;
	boolean isKwang;
	
	SutdaCard(){
		this(1, true);	//SutdaCard(1, true)를 호출
	}
	
	SutdaCard(int num, boolean isKwang){
		this.num = num;
		this.isKwang = isKwang;
	}
	
	String info() {
		return num + (isKwang? "K" : "");
	}
}

 

[6-3] 다음과 같은 멤버변수를 갖는 Student클래스를 정의하시오.

	class Student{
		
		String name;
		int ban;
		int no;
		int kor;
		int eng;
		int math;
	}

 

[6-4] 문제6-3에서 정의한 Student클래스에 다음과 같이 정의된 두 개의 메서드 getTotal()과 getAverage()를 추가하시오.

public class practice {

	public static void main(String[] args) {
		Student s = new Student();
		s.name = "홍길동";
		s.ban = 1;
		s.no = 1;
		s.kor = 100;
		s.eng = 60;
		s.math = 76;
		System.out.println("이름:"+s.name);
		System.out.println("총점:"+s.getTotal());
		System.out.println("평균:"+s.getAverage());
		
	}
}
	class Student{
		
		String name;
		int ban;
		int no;
		int kor;
		int eng;
		int math;
		
		int getTotal() {
			return kor + eng + math;
		}
		
		float getAverage() {
			return (int)(getTotal() / 3f * 10 + 0.5f) / 10f;
		}
	}

마지막 소수점 둘째자리에서 반올림 하는 식의 설명의 예시는

236 / 3 -> 78
236 / 3f -> 78.666664
236 / 3f * 10 -> 786.66664
236 / 3f * 10 + 0.5 -> 787.16664
(int)(236 / 3f * 10 + 0.5) / 10 -> 78
(int)(236 / 3f * 10 + 0.5) / 10f -> 78.7

 

[6-5] 다음과 같은 실행결과를 얻도록 Student클래스에 생성자와 info()를 추가하시오.

결과 : 홍길동,1,1,100,60,76,236,78.7

		String name;
		int ban;
		int no;
		int kor;
		int eng;
		int math;
		
		Student(String name, int ban, int no, int kor, int eng, int math) {
			this.name = name;
			this.ban = ban;
			this.no = no;
			this.kor = kor;
			this.eng = eng;
			this.math = math;
		}
		
		int getTotal() {
			return kor + eng + math;
		}
		
		float getAverage() {
			return (int)(getTotal() / 3f * 10 + 0.5f) / 10f;
		}

		public String info() {
			return name
					+ "," + ban
					+ "," + no
					+ "," + kor
					+ "," + eng
					+ "," + math
					+ "," + getTotal()
					+ "," + getAverage()
					;

 

[6-6] 두 점의 거리를 계산하는 getDistance()를 완성하시오. (제곱근 계산은 Math.sqrt(double a)를 사용)

결과 : 1.4142135623730951
public class practice {
	
	//두 점 (x,y)와 (x1, y1)간의 거리를 구한다.
	static double getDistance(int x, int y, int x1, int y1) {
		return Math.sqrt( (x - x1) * (x - x1) + (y - y1) * (y - y1));
		}
		
public static void main(String[] args) {
	System.out.println(getDistance(1,1,2,2));
	}
}

 

[6-7] 문제6-6에서 작성한 클래스메서드 getDistance()를 MyPoint클래스의 인스턴스메서드로 정의하시오.

double getDistance(int x1, int y1){
		return Math.sqrt((x - x1) + (x - x1) + (y - y1) * (y - y1));
	}

6-6번의 static메서드와 인스턴스 메서드의 차이점을 이용한 문제.

static메서드에서는 인스턴스 변수를 사용하지 않고 매개변수(지역변수)로 작업에 필요한 값을 제공받았고,

인스턴스메서드에서는 인스턴스 변수 x, y를 이용해서 작업하므로 매개변수 x1, y1만 제공받으면 됨

(여기서 지역변수, 인스턴스변수를 구분하는 것이 이해가 안 간다..)

 

[6-8] 다음의 코드에 정의된 변수들을 종류별로 구분해서 적으시오.

- 클래스변수(static변수) : width; , height; 

- 인스턴스변수 : kin, num

- 지역변수 : k, n, card, args

 

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

static int weapon = 6;

static int armor = 0;

=>모든 병사의 공력력과 방어력은 같아야 하므로

 

static void weaponUp() {

   weapon++;

}

static void armorUP() {

   armor++;

}

=>위의 static변수에 대한 작업을 하는 메소드이므로

 

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

답 :

b. 생성자는 객체를 생성하기 위한 것이다.

-> 생성자가 객체를 생성할 때 사용되기는 하지만, 객체를 초기화할 목적으로 사용되는 것이다. 객체를 생성하는 것은 new연산자이다.

e. 생서자는 오버로딩 할 수 없다.

-> 생성자도 오버로딩이 가능해서 하나의 클래승 여러 개의 생성자를 정의할 수  있다.

 

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

답 : 

b. 클래스 내에서라면 어디서든 사용할 수 있다.

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

 

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

답 : 

c. 리턴타입이 달라야 한다. -> 리턴타입은 오버로딩에 영향을 주지 못한다.

d. 매개변수의 이름이 달라야 한다. -> 매개변수의 이름이 같아야 한다.


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

답 : b, c, d 모두 메소드의 이름이 add이고 매개변수 타입이 다르므로 오버로딩이 성립된다.

 

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

답 : c, e

-> 클래스변수는 클래스가 처음 메모리에 로딩될 때, 자동 초기화되므로 인스턴스 변수보다 먼저 초기화된다.

그리고 생성자는 초기화블럭이 수행된 다음에 수행된다.

 

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

답 : a

 

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

답 : a, e

지역변수는 자동 초기화 되지 않기 때문에 사용하기 전에 반드시 초기화를 해주어야한다.

지역변수는 자신이 선언된 블럭이나 메소드가 종료되면 소멸되므로 메모리 부담이 적다.

힙(heap)영역에는 인스턴스(인스턴스변수)가 생성되는 영역이며, 지역변수는 호출스택(call stack)에 생성된다.

 

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

답 : b -> 호출스택의 맨 위에 있는 메소드가 현재 수행중인 메소드이며, 호출스택 안의 메소드들은 대기상태이다.

 

[6-18] 다음의 코드를 컴파일하면 에러가 발생한다. 컴파일 에러가 발생하는 라인과 그 이유를 설명하시오.

답 :

라인A -> static변수에 인스턴스변수 사용 못함

라인B -> static메소드 안에서 인스턴스변수 출력 못함

라인D -> static메소드 안에서 인스턴스메소드 수행 못함

 

[6-19] 다음 코드의 실행 결과를 예측하여 적으시오.

답 : 

ABC123

After change : ABC123

 

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

[주의] Math.random()을 사용하는 경우 실행결과와 다를 수 있음.

public class Exercise6_20 {

	public static int[] shuffle(int[] arr) {
		if(arr == null || arr.length == 0)
			return arr;
		
		for(int i = 0; i < arr.length; i++) {
			int j = (int)(Math.random() * arr.length);
			
			int tmp = arr[i];
			arr[i] = arr[j];
			arr[j] = tmp;
		}
		return arr;
	}
	public static void main(String[] args) {

		int[] original = {1, 2, 3, 4, 5, 6, 7, 8, 9};
		System.out.println(java.util.Arrays.toString(original));
		
		int[] result = shuffle(original);
		System.out.println(java.util.Arrays.toString(result));
	}

}

 

[6-21] Tv클래스를 주어진 로직대로 완성하시오. 완성한 후에 실행해서 주어진 실행결과와 일치하는지 확인하라.

	void turnOnOff() {
	// (1) isPowerOn의 값이 true면 false로, false면 true로 바꾼다.
		isPowerOn = !isPowerOn;
	}
	void volumeUp() {
		// (2) volume의 값이 MAX_VOLUME보다 작을 때만 값을 1증가시킨다.
		if(volume < MAX_VOLUME) {
			volume++;
		}
	}
	void volumeDown() {
		// (3) volume의 값이 MIN_VOLUME보다 클 때만 값을 1감소시킨다.
		if(volume > MIN_VOLUME) {
			volume--;
		}
	}
	void channelUp() {
		// (4) channel의 값을 1증가시킨다.
		// 만일 channel이 MAX_CHANNEL이면, channel의 값을 MIN_CHANNEL로 바꾼다.
		if(channel == MAX_CHANNEL) {
			channel = MIN_CHANNEL;
		} else {
			channel++;
		}
	}
	void channelDown() {
		// (5) channel의 값을 1감소시킨다.
		// 만일 channel이 MIN_CHANNEL이면, channel의 값을 MAX_CHANNEL로 바꾼다.
		if(channel == MIN_CHANNEL) {
			channel = MAX_CHANNEL;
		} else {
			channel--;
		}

 

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

public class Exercise6_22 {

	public static boolean isNumber(String str) {
		if(str == null || str.equals("")) 
			return false;
		
		for(int i = 0; i < str.length(); i++) {
			char ch = str.charAt(i);
			
			if(ch < '0' || ch > '0') {
				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));
		
	}

}

 

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

public class Exercise6_22 {

	public static int max(int[] arr) {
		if(arr == null || arr.length == 0) 
			return -999999;
			
			int max = arr[0];
			
			for(int i = 1; i < arr.length; i++) {
				if(arr[i] > max)
					max = arr[i];
			}
			return max;
		}
		
	
	public static void main(String[] args) {
		
		int[] data = {3,2,9,4,7};
		System.out.println(java.util.Arrays.toString(data));
		System.out.println("최대값:"+max(data));
		System.out.println("최대값:"+max(null));
		System.out.println("최대값:"+max(new int[]{})); // 크기가 0인 배열
		
	}

}

 

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

public class Exercise6_24 {

	public static int abs(int value) {
		return value >= 0 ? value : -value;
	}
		
	public static void main(String[] args) {
		
		int value = 5;
		System.out.println(value+"의 절대값:"+abs(value));
		value = -10;
		System.out.println(value+"의 절대값:"+abs(value));
		
	}

}