LANGUAGE/Java
자바의 정석(기초편) - 연습문제(객체지향 프로그래밍II)
Doraemon_lulu
2023. 11. 26. 19:50
연습문제
1번
package Exercise;
class SutdaDeck {
final int CARD_NUM = 20;
SutdaCard[] cards = new SutdaCard[CARD_NUM]; // 길이가 20인 새로운 배열 cards 생성
SutdaDeck() {
for (int i = 0; i < cards.length; i++) {
int num = (i % 10) +1; // num 변수의 범위: 1 ~ 10
boolean isKwang = (i < 10) && (num == 1 || num == 3 || num == 8);
cards[i] = new SutdaCard(num, isKwang);
}
}
}
class SutdaCard{
int num; // iv
boolean isKwang; // iv
SutdaCard() { // 매개변수 없는 생성자
this(1, true); // iv 변수 각각에 값 대입
}
SutdaCard(int num, boolean isKwang) { // 매개변수 있는 생성자
this.num = num; // 매개변수에 iv 변수값(1) 대입
this.isKwang = isKwang; // 매개변수에 iv 변수값(true) 대입
}
public String toString() { // 문자열 출력 시 실행됨.
return num + (isKwang? "K" : ""); // isKwang이 true면 K, false면 빈문자열("")
}
}
public class Exercise07_01 {
public static void main(String[] args) {
SutdaDeck deck = new SutdaDeck(); // SutdaDeck의 새로운 객체 deck 생성 및 초기화
for (int i = 0; i < deck.cards.length; i++) { // i가 0 ~ 19 까지 반복
System.out.print(deck.cards[i] + ","); // cards 배열 각 자리 값 출력
}
}
}
출력 결과
1K,2,3K,4,5,6,7,8K,9,10,1,2,3,4,5,6,7,8,9,10,
|
2번
이미 정의된 배열의 값을 섞어서 다시 새로운 배열로 출력하는 기능 추가
package Exercise;
class SutdaDeck2 {
final int CARD_NUM = 20;
SutdaCard[] cards = new SutdaCard[CARD_NUM];
SutdaDeck2() {
for (int i = 0; i < cards.length; i++) {
int num = (i % 10) +1; // 1 ~ 10
boolean isKwang = (i < 10) && (num == 1 || num == 3 || num == 8);
cards[i] = new SutdaCard(num, isKwang);
}
}
void shuffle() {
for (int i = 0; i < cards.length; i++) {
int j = (int)(Math.random() * cards.length); // j의 범위: 0이상, 20미만
// 배열 내 저장된 값들을 무작위로 위치 재설정하여 섞는 방법
SutdaCard tmp = cards[i]; // SutdaCard의 새로운 배열 tmp 생성 및 cards[i] 값으로 초기화
cards[i] = cards[j]; // card[i]에 cards[j] 값을 대입
cards[j] = tmp; // card[j]에 tmp 값을 대입
}
}
SutdaCard pick(int index) { // 배열위치(index)에 따른 cards 배열값 확인
if (index < 0 || index >= CARD_NUM)
return null;
return cards[index];
}
SutdaCard pick() {
int index = (int)(Math.random() * cards.length); // index 범위는 0이상, 20미만
return pick(index); // pick(int index) 호출
}
}
class SutdaCard2{
int num; // iv
boolean isKwang; // iv
SutdaCard2() { // 매개변수 없는 생성자
this(1, true); // iv 변수 각각에 값 대입
}
SutdaCard2(int num, boolean isKwang) { // 매개변수 있는 생성자
this.num = num; // 매개변수에 iv 변수값(1) 대입
this.isKwang = isKwang; // 매개변수에 iv 변수값(true) 대입
}
public String toString() { // 문자열 출력 시 실행됨.
return num + (isKwang? "K" : "");
}
}
public class Exercise07_02 {
public static void main(String[] args) {
SutdaDeck2 deck = new SutdaDeck2();
System.out.println(deck.pick(0));
System.out.println(deck.pick());
deck.shuffle();
for (int i = 0; i < deck.cards.length; i++) {
System.out.print(deck.cards[i] + ",");
}
System.out.println();
System.out.println(deck.pick(0));
}
}
출력 결과
1K
9 // deck.pick()의 결과는 실행할 때마다 매번 새로운 값으로 출력됨. 9,8K,10,6,9,7,10,2,5,5,4,8,3,7,4,1,3K,2,1K,6, 9 // deck.pick()의 결과는 실행할 때마다 매번 새로운 값으로 출력됨. |
4번
getter/setter의 활용
- setter를 통해 매개변수 값이 저장된 위치의 주소를 인스턴스 변수가 가리키도록 선언함.
- getter를 통해 인스턴스 변수를 호출하여 원하는 값을 반환함.
*** 매개변수가 있는 메서드의 경우, 반드시 넘겨받은 값의 유효성 검사를 해야 함!!
예를 들어,
아래 코드의 main 메서드에서 10이라는 volume을 매개변수로 넘겨 받았고, 10이라는 값이 기존에 선언한 상수인 volume의 최소, 최대값 범위 내에 속하는지 유효성 검사를 시행해야 함.
package Exercise;
class MyTv {
// iv (인스턴스 변수)
private boolean isPowerOn;
private int channel;
private int volume;
// 상수
final int MAX_VOLUME = 100;
final int MIN_VOLUME = 0;
final int MAX_CHANNEL = 100;
final int MIN_CHANNEL = 1;
// setter
public void setVolume(int volume) {
if (volume > MAX_VOLUME || volume < MIN_VOLUME)
return;
this.volume = volume; // 매개변수(volume) 값을 인스턴스변수(this.volume)에 저장됨.
}
// getter
public int getVolume() {
return volume; // getVolume() 인스턴스 호출 시 인스턴스 변수(volume) 반환됨.
}
// setter
public void setChannel(int channel) {
if (channel > MAX_CHANNEL || channel < MIN_CHANNEL)
return;
this.channel = channel; // 매개변수(channel) 값이 인스턴스변수(this.channel)에 저장됨.
}
// getter
public int getChannel() {
return channel; // getChannel 호출 시 인스턴스변수(channel) 반환됨.
}
}
public class Exercise07_04 {
public static void main(String[] args) {
MyTv tv = new MyTv();
tv.setChannel(10);
System.out.println("CH : " + tv.getChannel()); // getter 사용
tv.setVolume(20);
System.out.println("VOL : " + tv.getVolume()); // getter 사용
}
}
출력 결과
CH : 10
VOL : 20 |
5번
package Exercise;
class MyTv {
private boolean isPowerOn;
private int channel;
private int volume;
private int prevChannel; // 이전 채널을 저장하기 위한 인스턴스 변수 생성
final int MAX_VOLUME = 100;
final int MIN_VOLUME = 0;
final int MAX_CHANNEL = 100;
final int MIN_CHANNEL = 1;
public void setVolume(int volume) {
if (volume > MAX_VOLUME || volume < MIN_VOLUME)
return;
this.volume = volume;
}
public int getVolume() {
return volume;
}
public void setChannel(int channel) {
if (channel > MAX_CHANNEL || channel < MIN_CHANNEL)
return;
prevChannel = this.channel; // 현재 채널을 prevChannel 변수에 저장해둠.
this.channel = channel;
}
public int getChannel() {
return channel;
}
public void gottoPrevChannel() {
setChannel(prevChannel); // 현재 채널을 이전 채널로 변경하여 저장
}
}
public class Exercise07_04 {
public static void main(String[] args) {
MyTv tv = new MyTv();
tv.setChannel(10);
System.out.println("CH : " + tv.getChannel());
tv.setChannel(20);
System.out.println("CH : " + tv.getChannel());
// 이전 채널 호출하도록 함.
tv.gottoPrevChannel();
System.out.println("CH : " + tv.getChannel());
tv.gottoPrevChannel();
System.out.println("CH : " + tv.getChannel());
}
}
출력 결과
CH : 10
CH : 20 CH : 10 CH : 20 |
6번, 7번
package Exercise;
class Outer1 {
class Inner1 {
int iv = 100;
}
}
class Outer2 {
static class Inner2 {
int iv = 200;
}
}
public class Exercise07_06_07 {
public static void main(String[] args) {
// 인스턴스 클래스인 내부 클래스의 멤버변수 값 출력 (외부 클래스의 인스턴스 생성해야 함.)
Outer1 outer1 = new Outer1();
Outer1.Inner1 inner1 = outer1.new Inner1();
System.out.println(inner1.iv);
// 스태틱 클래스인 내부 클래스의 멤버변수 값 출력 (외부 클래스의 인스턴스 생성 불필요함.)
// 외부 클래스(Outer2) 객체 생성 없이 바로 내부 클래스(Inner2) 호출 가능
Outer2.Inner2 inner2 = new Outer2.Inner2();
System.out.println(inner2.iv);
}
}
출력 결과
100
200 |
8번
package Exercise;
class Outer{
int value = 10;
class Inner{
int value = 20;
void method1() {
int value = 30;
System.out.println(value); // 현재 메서드의 변수
System.out.println(this.value); // 내부 클래스의 인스턴스 변수
System.out.println(Outer.this.value); // 외부 클래스의 인스턴스 변수
}
}
}
public class Exercise07_08 {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.method1();
}
}
출력 결과
30
20 10 |
9번
package Exercise;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Exercise07_09 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.addWindowListener(new EventHandler());
}
}
class EventHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
e.getWindow().setVisible(false);
e.getWindow().dispose();
System.exit(0);
}
}
▼ EventHandler를 익명 클래스로 변경한 결과
package Exercise;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Exercise07_09 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
e.getWindow().setVisible(false);
e.getWindow().dispose();
System.exit(0);
}
});
}
}