자바프로그래밍 실습자료

 2 객체와 클래스에 익숙해지기 

 

 

클래스와 메소드의 헤더 바로 위에 주석을 적어야 합니다.

적지 않으면 1점 감점합니다.

 

표준라이브러리 API를 자주 찾아보아야 합니다. 찾아보는데 익숙해져야 합니다.

http://docs.oracle.com/javase/8/docs/api/

 

 

 

프로젝트 이름은 분반에 따라 “java2홍길동”혹은 “java3홍길동”으로 지으시오홍길동은 자신의 이름입니다.

매주 패키지를 새로 만들고 그 안에서 작업을 합니다.

2주에는 프로젝트 아래에 week2 패키지를 만들고 그 아래에서 작업을 합니다.

 

 

1.

한 가지 티켓만을 판매하는 간단한 기차표 자판기를 나타내는 TicketMachine 클래스를 작성하시오.

l  이 자판기는 구성(construct)될 때 얼마짜리 티켓을 판매할지가 정해집니다.

l  사용자는 이 자판기에 돈을 넣고 티켓을 출력합니다.

l  티켓을 출력하기 전에 돈을 여러 번 넣을 수 있습니다.

l  돈을 적게 넣고 티켓을 출력시키면 에러 메시지가 출력됩니다.

l  넣은 돈이 충분할 때 티켓을 출력시키면 티켓이 출력되고 잔액이 티켓 가격만큼 줄어듭니다.

l  자판기에 남아 있는 돈은 언제든지 되돌려 받을 수 있습니다.

 

TicketMachine을 이용하는 TicketMachineDemo 클래스의 예를 들면 아래와 같습니다.

 

 

TicketMachineDemo의 실행 결과는 아래와 같습니다.

 

위와 같이 작동이 되도록 TicketMachine 클래스를 작성하시오.

 

 

 

 

 

 

힌트: <프로그램 뼈대 예시>

 

2.

BlueJ를 실행하고 Eclipse로부터 TicketMachine.java 파일을 마우스로 끌어오시오. 그러면 화면에 TicketMachine 클래스를 나타내는 네모 박스가 만들어집니다. 네모박스를 더블클릭하세요. 그러면 편집창이 열리고 프로그램이 보입니다. TicketMachine 클래스 소스코드를 확인하고 “Close” 버튼을 클릭하여 편집창을 닫습니다.

만약, 소스코드의 한글이 깨지면 이클립스 편집창에서 프로그램을 복사하여 (control-a, control-c) BlueJ 편집창에 붙여넣기(엎어쓰기) (conrol-a, control-v) 줍니다.

 

BlueJ 편집창에서 소스코드에서package week2는 삭제합니다.

 

BlueJ 창의 TicketMachine 클래스 박스에 빗금이 쳐져 있음을 볼 수 있습니다. 소소 코드가 아직 컴파일되지 않았다는 의미입니다. 왼쪽에 있는 “Compile” 버튼을 클릭합니다. 빗금이 대부분 없어지고 두 줄만 남으면 제대로 컴파일이 됐다는 의미입니다.

 

1번에서 실행한 main 메소드와 같은 절차를 BlueJ에서 진행해 보시오. 2650원짜리 티켓을 판매하는 TicketMachine  인스턴스를 만든 후 이 객체에게 차례로 적절한 메소드들을 호출해야 합니다.

 

 

 

위와 같이 하는 대신 TicketMachineDeme 클래스도 이클립스에서 BlueJ로 복사하고 컴파일한 TicketMachineDemo main 메소드를 실행시킬 수도 있습니다. Main 메소드를 실행하면 main 프로그램 내에서 TicketMachine 인스턴스를 하나 만들고 그 인스턴스에게 여러 메소드를 차례로 호출하므로 위에서 한 수작업을 할 필요가 없습니다. 이렇게 하는 경우 main 프로그램 내에서 생성한 TicketMachine 인스턴스는 화면에 보이지 않습니다. 수작업으로 생성한 (화면에 빨간 색으로 보이는) TicketMachine 인스턴스와는 별개입니다.

 

이 문제의 결과물은 제출하지 않습니다.

 

3.

우선 java.awt.Rectangle 클래스의 grow 메소드와 union 메소드의 작동을 BlueJ를 이용해 확인합니다. 동영상

 

Eclipse에서 RectangleDemo라는 이름의 클래스를 작성합니다. 이 클래스에 main 메소드를 넣고 이 main 메소드에서 BlueJ에서 했던 것과 같은 조작을 하도록 하시오. 조작에 대한 설명과 조작 결과가 출력에 나타나도록 하시오. ( 1번 문제의 출력 참고).

 

아래는 출력 예입니다.

 

(참고)

RectangleDemo에서 java.awt.Rectangle라는 긴 이름 대신 간단히 Rectangle이라고 적으려면 이 클래스를 import해야 합니다. Eclipse 편집창에서는 control-O (대문자 O) 를 누르면 현재 클래스가 필요로 하는 모든 라이브러리 클래스들이 자동으로 import됩니다.

 

(힌트)

4.

자바 표준라이브러리에 있는 클래스의 인스턴스를 구성하고 이 객체에게 메소드를 호출하는 연습입니다.

 

로또 복권 번호 추천 프로그램을 작성하시오. 0 49를 포함하여 0 49사이의 숫자 여섯 개를 무작위로 선택하여 이들을 차례로 출력하면 됩니다. 우연히 같은 숫자가 반복되어도 좋습니다. 이와 같이 범위에 0 49를 포함하는 것을 inclusive라고 하고, 0 49를 제외하는 것을 exclusive라고 합니다. 클래스의 이름은 LottoNumber로 하시오. Java.util.Random 클래스 객체를 이용하시오.

 

무작위로 정수를 선택하기 위해서는 Random 클래스를 사용합니다. Random 클래스 객체를 하나 만들어 그 객체에게 nextInt 메소드를 호출하면 무작위로 정수를 반환합니다. 무작위 수가 하나 더 필요하면 Random 객체를 새로 만들 필요 없이 이미 만들어 놓은 Random 객체에게 한번 더 nextInt 메소드를 호출하면 됩니다.

 

API 문서에서 Random 클래스를 찾아 메소드 사용법을 읽어보시오. Random이 지원하는 nextInt 메소드는 아래와 같이 두 개가 있습니다.

int nextInt()  : 정수 난수를  반환

int nextInt(int n) : 0 이상 n 미만 정수 난수를 반환

 

 

아래는 프로그램 뼈대입니다.

 

 

 

아래는 실행화면입니다.

실행할 때마다 숫자가 다르게 나옵니다.

현재 선택된 애플리케이션을 실행시키는 단축키는 F11입니다.

 

 

(참고)

난수를 발생시키는 방법은 크게 두 가지가 있습니다.

Math 클래스의 static 메소드인 random() 메소드를 호출하는 방법

1학기 때 주로 사용했던 방법입니다. 간편하게 0.0 이상 1.0 미만 double 타입 난수를 만들 수 있습니다.

Random 클래스 인스턴스를 구성한 후 이 객체에게 필요한 (인스턴스) 메소드를 호출하는 방법

이 문제에서 사용하는 방법입니다. 여러 가지 메소드가 준비되어 있어 필요에 따라 골라 호출할 수 있습니다. 강력한 기능을 지원합니다.

 

 

 

5.

4번 문제에서는 main에서 Random 객체를 이용해 여섯 개의 난수를 만들었습니다.

이번에는 여섯 개의 “로또 번호 생성기 만들어 봅시다. LottoGenerator 클래스를 작성하고 그 인스턴스가 로또 번호를 만들도록 해 봅니다.

LottoGenerator 클래스는 로또 번호를 생성해 주는 generateNumbers라는 메소드를 갖도록 합니다.

LottoGenerator 인스턴스에게 generateNumbers라는 메소드를 호출하면 로또 복권에 적어 넣을 여섯 개의 숫자들을 가진 int 배열을 반환합니다.

int 배열을 반환한다는 말은 더 정확히는 int 배열을 가리키는 참조(reference)를 반환한다는 말입니다.

 

LottoGenerator로또 번호를 생성하기 위해 난수발생기가 필요합니다.

그래서 Random 타입 필드를 갖도록 하고 LottoGenerator 구성자에서 Random 인스턴스를 만들어 이 필드에 저장해 놓습니다.

 

아래는 프로그램 뼈대입니다.

 

 

 

LottoGenerator의 객체 다이어그램 (object diagram)은 아래와 같습니다.

 

 

 

LottoGenerator 객체를 이용하여 여섯 개의 숫자로 이루어진 로또 번호를 10번 만들어 보여주는 main 메소드를  작성하시오. 클래스 이름은 LottoGeneratorTest로 지으시오.

 

 

아래는 실행화면 예입니다.

 

 

 

 

6.

두 개의 주사위를 굴려 나오는 수의 합을 관찰하는 프로그램을 작성합니다.

우선 한 개의 주사위를 나타내는 Die 클래스를 작성합니다. 이 클래스의 코드가 아래에 있습니다.

 

 

다음으로는 주사위 두 개를 나타내는 Dice클래스를 작성합니다. 주사위(die)의 복수형이 dice입니다. 아래 코드를 완성하시오.

이 예에서는 Dice가 두 개의 Die 인스턴스들을 필드로 갖도록 했습니다.

두 개의 주사위를 던져야 할 때마다 이 두 주사위들을 던집니다.

주사위를 던질 때는 첫 주사위에 roll 메소드를 호출하고, 두 번째 주사위에도 roll 메소드를 호출하면 됩니다.

Dice 클래스의 roll 메소드와 Die 클래스의 roll 메소드는 이름은 같지만 서로 다른 메소드입니다.

 

(가)  Dice에게 roll 메소드를 호출하여 그 결과(주사위 두 개 쌍을 던져 나온 숫자의 합)를 화면에 출력하는 작업을 20회 반복하는 main 메소드를 작성하시오. 클래스 이름은 DiceCasting1으로 지으시오. 실행 예는 아래와 같습니다.

 

(나)  Dice에게 roll을 호출하면 그 반환값은 2 이상 12 이하입니다. Dice roll 1000번 호출하여 나온 값의 빈도수를 출력하는 main 메소드를 작성하시오. 클래스 이름은 DiceCasting2로 지으시오.
힌트: 0번 방부터 12번 방까지 총 13개의 방을 갖는 정수 배열을 만들고 n번 방에는 n이 나온 횟수를 기록합니다. 가령 2번 방에는 2가 몇 번이나 나왔는지를, 3번 방에는 3이 몇 번이나 나왔는지를 기록합니다.  0번 방과 1번 방은 사용하지 않습니다. (메모리는 낭비되지만 프로그램이 단순해집니다.)
실행 예는 아래와 같습니다.

 

 

7.

문자열의 글자 순서를 바꿔 만들어진 새 문자열을 반환하는 프로그램을 작성하시오.

클래스 이름은 Reverser로 짓고 그 클래스에 인스턴스 메소드를 구현하시오. 구현할 메소드는 아래 그림과 같이 두 가지입니다. 두 메소드는 다중정의(overloading)되는 셈입니다.

 

, 키보드로부터 한 줄짜리 문장 하나를 입력 받고 Reverser의 두 메소드를 이용하여 이 문장의 순서를 뒤집어 출력하는 프로그램을 작성하시오.

아래는 참고용 예시입니다.

 

위 프로그램의 실행 예는 아래와 같습니다.

 

 

reverse reverseWords 메소드를 구현하기 위해서는 문자열의 맨 끝 글자(혹은 단어)부터 시작하여 거꾸로 하나씩 차례로 조합해 나가야 합니다. 이 때 immutable 객체인 String을 사용하면 한 글자 조합할 때마다 새로운 객체를 구성하게 되어 비효율적이므로 String 대신 StringBuilder를 사용합니다. String의 메소드들 중 적당한 것을 찾아 사용하시오.

String의 메소드들 중 split이라는 메소드가 있습니다. 이 메소드는 string을 주어진 구분자를 기준으로 단어들을 추출하여 그 단어들을 String 배열로 반환합니다. 인터넷에서 사용 예를 찾아 보시오. reverseWords 메소드를 구현할 때 split 메소드를 사용하면 편리합니다.

 

 

8.

이 문제에서는 간단한 카이사르 암호(Caesar Cipher) 방식으로 암호화(encrypt), 복호화(decrypt) 기능을 구현합니다.

① 우선 인터넷 검색으로 “카이사르 암호”가 무엇인지 알아보시오.

② 또 “아스키코드”에서 영문자 ‘A’부터 ‘Z’까지의 글자는 어떤 코드 값을 갖는지 인터넷 검색을 통해 알아보시오. ASCII 코드

 

위 ①과 ② 한 후 아래 실습을 진행해야 합니다.

카이사르 암호화를 구현하는 CaesarCipher 클래스 뼈대가 아래 <Figure 1>에 있습니다.

이 클래스를 읽어보고 빈칸을 채워 완성하시오.

 

Message "ABC"일 때 이 messsaage알파벳표에서 오른쪽으로 2만큼 이동시켜 암호화하면 "CDE"가 됩니다. 복호화(암호를 풀어 줌)하면 다시 왼쪽으로 2 만큼 이동시켜 "ABC"가 됩니다.

다른 예가 아래 그림에 있습니다. 이 예에서는 3 만큼 이동시켜 암호화했습니다.

 

<Figure 1> 프로그램을 사용하는 경우, message의 각 글자를 알파벳표에서 5만큼 이동시켜 암호화하기 위해서는 translate(message, 5)를 호출하면 되고, 이렇게 암호화된 메시지인 cyperedMessage복호화하기 위해서는 translate(cypheredMessage, -5)를 호출함으로써 cypheredMessage의 각 글자를 알파벳표에서 -5만큼 이동시키면 됩니다.

 

문제를 단순화하기 위해 영어 글자만 허용하고 소문자가 입력되면 일단 대문자로 바꿔서 암호화하도록 합니다.

 

실행 예는 아래와 같습니다.

 

 

(참고 – Caesar cypher)

 

A’는 알파벳표 내에서의 위치가 0이이고

B’는 알파벳표 내에서의 위치가 1입니다. (B == A + 1)

Z’ 는 알파벳표 내에서의 위치가 25입니다. (Z == A + 25)

이들을 오른쪽으로 2만큼씩 이동하면 각각

C (알파벳표 내에서의 위치는 2)

D (알파벳표 내에서의 위치는 3)

B (알파벳표 내에서의 위치는 1)

가 됩니다.

 

즉 글자를 2만큼씩 오른쪽으로 이동하면

새 위치는 (알파벳표 내에서의 현재 위치 + 2 ) % 26

의 식으로 계산할 수 있습니다.

그러므로 새 글자는 (A + 새 위치) 입니다.

 

자바는 modulo 나머지 계산을 아래와 같이 합니다.

27 % 26 --> 1    (27 = 26 * 1 + 1)

-27 % 26 --> -1 (-27 = 26 * -1  -1)

 

알파벳표 내에서의 위치가 -1로 계산됐다면 여기에 26을 더해 25로 만들어 주어야 합니다.

, 알파벳에서 위치가 -1이라는 것은 ‘A’보다 한 칸 왼쪽에 있다는 것이므로 ‘Z’를 의미합니다.

그러니까 -1 + 26 --> 25가 올바른 위치입니다.

 

(참고 – char 타입과 아스키코드)

char c = A;

위와 같은 문장이 실행되면 변수 c에는 숫자 65가 저장됩니다. 아스키코드표에서 보면 'A'의 코드가 65이기 때문입니다. 변수 c를 출력하면 'A'가 화면에 출력됩니다. 변수 c char 타입으로 선언되어 있기 때문입니다.

이어서 아래와 같은 코드를 실행하면 변수 d에는 숫자 68이 저장됩니다.

char d = 'A' + 3;

변수 d를 출력하면 'D'가 화면에 출력됩니다. 변수 d char 타입으로 선언되어 있고 'D'아스키코드가 68이기 때문입니다.

이어서 아래와 같은 코드를 실행하면 변수 i에는 숫자 3이 저장됩니다.

int i = d - 'A';

변수 i를 출력하면 3이 화면에 출력됩니다. 변수 i int 타입으로 선언되어 있고 i에 숫자 3이 들어 있기 때문입니다.

 

 

<Figure 1>

 

 

 

 

.