[자바] 2화 클래스, 객체 그리고 Scanner
이번에는 자바의 객체와 클래스에 대해 알아보고 문자나 숫자를 입력받는 일을 해보려고 합니다. Scanner를 이용해서 말이죠.
Scanner클래스는 자바에서 java.util.Scanner에 있는 클래스로, import를 해주어야만 사용할 수 있습니다.
Scanner클래스를 사용하려면 객체를 만들어야 하는데, 객체가 무엇인지 먼저 알아봅시다.
객체(Object)란?
클래스가 가진 기본 정보와 동일한 하나의 사물입니다. int나 char, float같은 자료형과 다르게, 힙(heap) 메모리에 저장되는 자료형이라 말할 수도 있고요. 간단하게 말하기에는 설명이 부족하니 그림으로 봅시다.
(보통은 붕어빵 틀과 붕어빵으로 설명하는데.. 다른 예제를 써서 해보겠습니다.)
객체를 소개하자면 위의 그림과 같다고 보시면 됩니다.
객체는 클래스를 바탕으로 만드는 변수와 같습니다. 위의 그림을 보면 Muffin이라는 클래스를 이용해서 잘 구워진 머핀과 보라색맛 날 것 같은 머핀 객체를 만들어냈죠.
(영화에서 나오는 클론을 생각하시면 됩니다. 클론들은 원본이 갖고 있는 형질을 갖습니다. 하지만 클론끼리도 모두가 동일하지는 않죠. 성격도, 이름도, 생각도 조금씩 다릅니다. 원본을 클래스, 클론을 객체라 생각하면 될 듯 합니다.)
Muffin클래스를 소스코드로 최대한 비슷하게 표현하자면 이렇게 표현할 수 있습니다.
public class Muffin { public static final int BROWN = 1; public static final int DARK_BROWN = 2; public static final int PURPLE = 3; public static final int CRIMSON_BROWN = 4; private int MuffinColor; private int PaperColor; public Muffin(int MuffinColor, int PaperColor) { this.MuffinColor = MuffinColor; this.PaperColor = PaperColor; } public int getMuffinColor() { return this.MuffinColor; } public int getPaperColor() { return this.PaperColor; } }
위 소스코드에서는 MuffinColor와 PaperColor를 객체를 만들 때 받습니다. 그래서 잘 구워진 머핀 색과 보라색맛 나게 생긴 머핀의 색깔이 다를 수 있는 것이죠. 위 소스코드에서 클래스 이름과 메소드 이름이 같은 것을 볼 수 있는데요, 위에 쓴 public Muffin(int MuffinColor, int PaperColor) { 를 생성자라고 부릅니다. ()모양의 괄호에는 사용자가 기본으로 받아야 할 값을 넣게 할 수 있습니다. (안 넣을 수도 있습니다.)
만약, 사용자가 생성자를 쓰지 않는다면, 자바는 알아서 아무 것도 없는 생성자를 만듭니다. 아래처럼 말이죠.
public Muffin() {
}
Muffin클래스를 간단히 만들어본 김에 Muffin객체도 만듭시다.
Muffin BakedMuffin = new Muffin(Muffin.BROWN, Muffin.DARK_BROWN); //잘 구워진 머핀의 객체생성 Muffin OddMuffin = new Muffin(Muffin.PURPLE, Muffin.CRIMSON_BROWN); //보라색맛 머핀의 객체생성
이렇게 표현할 수 있겠네요. 여기서 중요히 여겨야 할 부분이 두 개 있습니다.
첫 번째는 new 예약어와 생성자()입니다.
new 예약어는 자바에서 객체를 만들 때 사용합니다. 간혹 new를 안 쓰고 객체가 생성되지 않아 난항을 겪는 분들이 계시기 때문에 그 중요성을 강조하고 싶습니다. 또한 () 모양의 생성자인데요. 제가 만든 Muffin객체를 만들기 위해서는 머핀의 색과 머핀을 두를 종이의 색깔을 쓰도록 했습니다. (int MuffinColor와 int PaperColor입니다.)
두 번째는 Muffin.BROWN 부분입니다.
생각해보세요. 우리는 아직 Muffin 객체를 만들지 않았습니다. 그런데 어떻게 Muffin.BROWN을 쓸 수 있었을까요?
이는 Muffin 클래스를 봐야 알 수 있습니다. Muffin클래스에서 아래와 같이 정의되어 있습니다.
public static final int BROWN = 1; public static final int DARK_BROWN = 2; public static final int PURPLE = 3; public static final int CRIMSON_BROWN = 4;
static을 썼기 때문입니다. static은 1화'public static void main편에서 설명드렸듯이 메모리에 바로 올라갑니다. 그러므로 객체를 생성하지 않아도 Muffin.BROWN을 쓸 수 있는 것입니다. 또한 final을 사용하여 BROWN을 상수로 만들었습니다. 그러므로 사용자가 실수로 Muffin.BROWN = 2; 로 만들어서 프로그램이 꼬이는 경우를 막아주었습니다.
그러면 왜 이렇게 static을 써서 public static int BROWN같은 것을 정의해놓은 것일까요? 이는 소스코드를 보다 직관적으로 볼 수 있기 때문입니다. 아래의 예문을 제 3자가 볼 때 어떤 것이 바로 이해가는지는 물어볼 필요도 없을 겁니다.
Muffin BakedMuffin = new Muffin(Muffin.BROWN, Muffin.DARK_BROWN); //직관적인 코드 Muffin BakedMuffin = new Muffin(1, 2); //직관적이지 않은 코드
클래스와 객체의 관계. 설명으로 보니 크게 어렵지 않습니다.
클래스와 객체에 대한 설명을 끝냈으니 이제 Scanner클래스를 이용하여 값을 받아봅시다.
import java.util.Scanner; public class ScannerExample { public static void main(String[] args) { System.out.println("받을 값을 입력해주세요."); Scanner input = new Scanner(System.in); } }
위 소스코드는 Scanner 객체를 만들어서 값을 받는 소스코드입니다. 앞에서 공부해본 것을 토대로 설명해보자면, 객체명이 input인 Scanner클래스의 객체인데 생성자로 System.in을 받았군요. System.in은 static을 썼을 것이고요.
이제 앞에서 공부했던 것과 별개로 Scanner에 대해 알아보겠습니다.
Scanner는 값을 받기만 합니다. 즉, 받은 값은 어디론가 받을 때마다 저장해야 된다는 뜻이죠.
값을 받기 위한 메소드들을 아래 나열하였습니다.
Method |
Description |
next() |
다음에 위치한 토큰을 String타입으로 가져옵니다. |
nextLine() |
Enter를 치기 이전까지의 줄을 String타입으로 가져옵니다. |
nextByte() |
다음에 위치한 토큰을 Byte타입으로 가져옵니다. |
nextShort() |
다음에 위치한 토큰을 Short타입으로 가져옵니다. |
nextInt() |
다음에 위치한 토큰을 Int타입으로 가져옵니다. |
nextFloat() |
다음에 위치한 토큰을 Float타입으로 가져옵니다. |
nextDouble() |
다음에 위치한 토큰을 Double타입으로 가져옵니다. |
여기서 토큰(Token)이라는 단어를 사용하였는데, 토큰은 자바가 구분하는 단위입니다. 일반적으로 띄어쓰기로 토큰을 나누며 Hello World의 경우 Hello와 World로 토큰이 나뉩니다.
이제 메소드를 이용해서 값들을 받아봅시다.
import java.util.Scanner; public class ScannerExample { public static void main(String[] args) { Scanner input = new Scanner(System.in); String first = input.nextLine(); int second = input.nextInt(); String third = input.next(); System.out.println(first); System.out.println(second + " " + third); } }
위 소스코드를 실행하여 값을 입력하면 아래와 같은 결과가 나옵니다. (결과가 작네요.)
오늘은 간단하게 클래스와 객체의 관계, 그리고 Scanner를 이용해서 값을 받는 방법을 알아봤습니다. 여러 메소드들을 잘 조합하면 문자열에서 문자를 받는 것도 가능하고 영문자를 대문자에서 소문자로 만드는 일도 가능합니다. 오늘도 자바자바하세요!
'자바 > 자바기초' 카테고리의 다른 글
[자바] 6화 오버로딩&오버라이딩(overloading / overriding) (0) | 2016.04.07 |
---|---|
[자바] 5화 예외발생/이양(throw/throws) (0) | 2016.04.03 |
[자바] 4화 예외처리(try,catch,finally / throws) (0) | 2016.04.02 |
[자바] 3화 상속(extends) (0) | 2016.03.31 |
[자바] 1화 public static void main(String[] args) (4) | 2016.03.06 |
[자바] 1화 public static void main(String[] args)
이클립스 설치는 다른 분들의 블로그를 참조해서 설치하시면 됩니다. (요즘은 폰으로 배우시겠다는 분들도 많아서 IDE의 선택이 워낙 다양한지라.)
(IDE: 통합 개발 환경의 약자입니다. 메모장의 경우 소스를 입력할 수 있지만 컴파일은 불가능하죠. 컴파일러만 있으면 소스 입력은 불가능하고요. 통합 개발 환경이라는 말은 메모장+컴파일러+디버거 이 세 가지를 합쳐놓은 프로그램이라 생각하시면 편합니다.)
제 포스팅의 편의를 위해 깔려있는 이클립스를 사용하며 설명 이해는 이클립스를 쓰실 때 가장 편합니다.
workspace를 지정하고 Welcome 팝업(?)을 업애면 이 화면과 비슷한 화면이 뜹니다.
좌측에 있는 Package Explorer 아래의 넓은 하얀 판을 우클릭하시면
이렇게 뜹니다. 정확히는 New에 마우스 올리셔야 이렇게 뜨죠. 우리는 자바 프로그래밍을 하므로 Java Project를 누릅니다.
대충 프로젝트의 이름을 정하고 Finish를 누릅니다.
이런식으로 프로젝트가 만들어집니다. 위에서는 Project_NAME이라고 써놨지만 사실 전 JAVA_1이라고 썼습니다.
src위에 마우스 우클릭하신 뒤 New - Class 를 누르셔서 클래스를 하나 만드시면 됩니다.
(Class란 자바에서 프로그램의 단위입니다. 게임을 예로 들 경우, Player클래스나 Slime클래스를 연상하면 쉽습니다.)
저는 클래스 이름을 java_1라고 썼습니다. (참고로 클래스 이름은 첫 글자 대문자가 좋아요. 전 이미 글렀기 때문에 소문자로..)
자, 클래스까지 만드셨다면(그리고 클래스 이름이 java_1이라면) 여러분은 아래와 같은 소스를 보실 수 있습니다.
public class java_1 { }
위의 소스를 아래처럼 바꿔봅시다.
public class java_1 { public static void main(String[] args) { } }
C에서 int main(void)를 선언했다면, 자바에서는 public static void main(String[] args)를 선언합니다.
C에 비해 상당히 길지만 이해하면 어렵지 않습니다.
public. 접근 제한자이며 public말고도 protected default private가 있습니다.
(default는 아무 것도 쓰지 않을 경우 자동으로 default로 처리합니다.)
static. 전역 변수로 만들어줍니다. 또한 static이 붙으면 램에 먼저 올라갑니다.
(main함수는 프로그램의 시작점이기 때문에 램에 가장 먼저 올라가 있어야 합니다.)
static을 쓸 경우 정적 메소드라 하여 이후에 다룰 '객체'를 선언하지 않아도 사용할 수 있습니다.
void. C에서와 같은 의미입니다. 반환값을 갖지 않습니다.
(만약 void 외의 자료형을 선언하면 기본 메소드는 void형을 사용해야 한다고 오류 문구를 출력합니다.)
main. 자바에서 나타내는 시작점의 이름입니다. 다른 이름으로 사용하면 자바가 알아먹지 못합니다.
(프로그램의 시작점을 못 찾기 때문에 프로그램이 작동되지 않습니다.)
(String[] args). 많은 분들이 사실 String[] args를 그냥 씁니다.(하지만 의미는 있습니다.)
args는 arguments의 약자이며 그저 그런 변수명이므로 asdf처럼 취향따라 바꿔서 써도 무방합니다.
args는 띄어쓰기(스페이스 바)를 분리자로 인식하는 문자열 배열입니다.
즉, I am John이라고 쓰면 I는 args[0], am은 args[1], John은 args[2]가 됩니다.
(배열이란 비슷한 자료형을 쉽게 모아서 사용할 수 있도록 만든 자료형의 일종입니다.)
흔한 Hello World 대신에 (String[] args)를 이해할 수 있는 소스를 작성해보겠습니다.
public class java_1 { public static void main(String[] args) { System.out.println(args[0] + args[1]); } }
위와 같이 소스를 작성했다면 이제 Export를 하여 jar형식의 실행파일로 만들어야 합니다.
(IDE 내에서 run을 통해 테스트하는 방법은 불가능합니다.)
Package Explorer에서 현재 진행하고 있는 프로젝트를 우클릭한 후 중간 쯤에 있는 Export를 누릅니다.
JAR file을 선택한 후 Next할 수 없을 때까지 Next를 누릅니다.
Next를 누를 수 없을 때까지 가면 위와 같은 창이 뜨는데 여기서 Main class를 지정해주어야 프로그램이 돌아갑니다.
Finish를 누르면 Export가 끝납니다! 이제 우리가 만든 jar파일을 실행시킬 일만 남았습니다.
만든 jar파일을 파란줄 친 곳으로 옮긴 뒤
java -jar [파일명].jar Hello World를 입력하시면 String[]이 인식하여 Hello World를 출력합니다.
이렇게 String[]을 사용하여 Hello World를 출력하였습니다.
지금 만든 소스는 사실 단점이 하나 있습니다. 띄어쓰기를 두 번 이상 할 수 없다는 점이죠.
(즉 Hello World, Cat Dog, apointment Whatthe 처럼 간단하게 쓸 수 밖에 없죠)
예외처리와 반복문을 이용하면 위의 문제를 해결할 수 있습니다.
만약 계속 문자열을 받아서 출력할 수 있는 소스에 관심이 있다면 아래 링크에서 다운받으시면 됩니다.
(소스 안에 설명도 달아놓았습니다.)
'자바 > 자바기초' 카테고리의 다른 글
[자바] 6화 오버로딩&오버라이딩(overloading / overriding) (0) | 2016.04.07 |
---|---|
[자바] 5화 예외발생/이양(throw/throws) (0) | 2016.04.03 |
[자바] 4화 예외처리(try,catch,finally / throws) (0) | 2016.04.02 |
[자바] 3화 상속(extends) (0) | 2016.03.31 |
[자바] 2화 클래스, 객체 그리고 Scanner (2) | 2016.03.20 |