-
5. 자바 메서드자바(Java) 강의 2019. 3. 25. 11:55
배열과 반복문을 통해 우리는 어떻게 하면 반복적으로 나타나는 코드를 간결하게 줄일 수 있는지 알아보았다. 하지만 때로는 반복문이 모든걸 해결 해 주지 않는다. 이번 포스트에서는 자바의 메서드가 어떤 문제를 해결하는지, 왜 사용하는지, 그리고 어떻게 사용하는지에 대해 알아보도록 하겠다.
예상 독자
- 자바를 배우고 싶은 누구나
- JDK와 IDE를 설치한 자바 학습자. ( 1. 자바 설치 및 개발환경 설정 )
- char를 공부한 자바 학습자. ( 2. 자바 변수와 자료형 (1) char )
- boolean을 공부한 자바 학습자. ( 2. 자바 변수와 자료형 (2) boolean )
- byte, short, int, long을 공부한 자바 학습자. ( 2. 자바 변수와 자료형 (3) byte, short, int, long )
- float과 double을 공부한 자바 학습자. ( 2. 자바 변수와 자료형 (4) float, double )
- if-else문의 사용 방법을 알고있는 자바 학습자. ( 3. 자바 조건문 (1) if-else )
- 자바 배열을 공부한 자바 학습자. ( 4. 자바 배열과 반복문 (1) 배열, 4. 자바 배열과 반복문 (3) 중첩 배열 )
- 자바 반복문 for 문을 공부한 자바 학습자 ( 4. 자바 배열과 반복문 (2) 반복문, 4. 자바 배열과 반복문 (4) 중첩 반복문 )
- 반복문을 충분히 공부한 자바 학습자 (4. 자바 배열과 반복문 (4) 연습 - 배열의 최댓값 구하기)
- 자바 반복문 while 문을 공부한 자바 학습자 (4. 자바 배열과 반복문 (5) while)
목표
- 메서드 (Method)
- 메서드 정의(선언) (Method Signature)
- 메서드 사용
- 코드가 실행되는 과정
- 메인 메서드
- System.out.println
- 메서드를 사용하능 이유
메서드 (Method)
수 세개의 합계, 평균, 최솟값, 최댓값을 출력하는 코드를 짜보자.
public class Main {
public static void main(String[] args) {
int x = 3;
int y = 5;
int z = 10;
int s = (x + y + z);
int avg = (x + y + z)/3;
System.out.println("합 : " + s);
System.out.println("평균 : " + avg );
int min = x;
if (min > y) {
min = y;
}
if (min > z) {
min = z;
}
System.out.println("최솟값 : " + min);
int max = x;
if(max < y) {
max = y;
}
if(max < z) {
max = z;
}
System.out.println("최댓값 :" + max);
}
}
실행 결과: 합 : 18 평균 : 6 최솟값 : 3 최댓값 :10이제 이 밑에 또 다른 세 수의 합, 평균, 최솟값, 최댓값을 구하는 코드를 적어보자.참고 "합 : " + s <- 문자를 이어붙이는 것이다.
public class Main {
public static void main(String[] args) {
int x = 3;
int y = 5;
int z = 10;
int s = (x + y + z);
int avg = (x + y + z)/3;
System.out.println("합 : " + s);
System.out.println("평균 : " + avg );
int min = x;
if (x > y) {
min = y;
}
if (y > z) {
min = z;
}
System.out.println("최솟값 : " + min);
int max = x;
if(x < y) {
max = y;
}
if(y < z) {
max = z;
}
System.out.println("최댓값 :" + max);
// 두번째
int i = 13;
int j = 5;
int k = 10;
s = (i + j + k);
avg = (i + j + k)/3;
System.out.println("합 : " + s);
System.out.println("평균 : " + avg );
int min_2 = i;
if (min_2 > j) {
min_2 = j;
}
if (min_2 > k) {
min_2 = k;
}
System.out.println("최솟값 : " + min_2);
int max_2 = i;
if(max_2 < j) {
max_2 = j;
}
if(max_2 < k) {
max_2 = z;
}
System.out.println("최댓값 :" + max_2);
}
}
실행 결과: 합 : 18 평균 : 6 최솟값 : 3 최댓값 :10 합 : 28 평균 : 9 최솟값 : 5 최댓값 :10뭔가 자꾸 반복되는 느낌이 들지 않는가? 이를 해결하기 위해 물론 반복문을 사용 할 수 있으나, 반복문을 사용하지 못한다고 가정하면 어떻게 해결해야 할까? 위의 코드를 보면 x, y, z또는 i, j, k등 변수의 이름만 바뀔 뿐 수가 3개 필요하다는 것, 반복되는 연산을 한다는 것을 알 수 있다. 이렇게 반복적으로 나타나는 같은 기능을 하는 코드를 묶어서 재사용 할 수 있을까? 있다. 그리고 그렇게 만들어진 '재사용 가능한 가장 작은 코드의 단위'를 메서드(또는 다른 언어에서는 함수)라고 부른다. 그렇다면 메서드는 어떻게 만들까?메서드 정의(선언) (Method Signature)
리턴값의_자료형 메서드_이름(매개변수의_자료형1 매개변수_이름1, 매개변수의_자료형2 매개변수_이름2) { // 재사용하고자 하는 코드
}- 리턴값의_자료형(또는 자료구조) - 기본적인 메서드 문법은 리턴값의 자료형으로 시작된다. 자바의 메서드는 메서드를 실행 후 하나의 값을 리턴 할 수 있다. 이 값의 자료형이 무엇인지 명시해야줘야 하는데 그것을 메서드 선언의 가장 첫 부분에서 한다. 따라서 가장 첫부분에는 int, char, double등등 자료형이 나온다. 리턴하는 값이 없는 경우 void (아무것도 없음을 표현하는 자료형)을 적어준다.
- 메서드_이름 - 리턴값의 자료형을 명시한 후에는 이 메서드에 이름을 붙여준다. 이 메서드 이름으로 우리는 메서드를 콜 할 것이다.
- 괄호와 매개변수 - 메서드 이름 다음에는 이 메서드가 받을 매개변수를 넘겨준다. 매개변수는 0개든, 몇개든 가능하다. 대신 매개변수(Parameters)를 적어 줄 때는, 매개변수의 자료형(또는 자료구조) 이 메서드 내에서 사용할 매개변수의 이름을 콤마로 나누어 나열 해 준다.
- {} - 꺽쇠괄호 안에 있는 부분을 메서드의 바디(Body)라고 부른다. 이 부분에 바로 재사용 될 코드가 들어간다.
참고! 위에서 말하는 자료구조는 클래스를 의미한다. 이에 대한 이야기는 다음 포스트에서 하도록 한다.이제 위의 예를 가지고 한번 메서드를 알아보도록 하자.void stats(int a, int b, int c) { // 재사용하고자 하는 코드
}우리는 리턴 할 값이 없으므로 일단 void로 리턴 값을 지정 해 주었다. 또한 여러가지 통계값을 출력하므로 메서드의 이름을 stats으로 지정했다. 메서드의 이름을 이와같이 메서드가 할 일을 직접적으로 나타내는게 좋다. 우리는 세개의 수를 이용해 통계값을 출력하므로 int 로 선언된 변수 세개를 매개변수로 받는다. 이 a, b, c는 위의 x, y, z또는 i, j, k를 대신 할 변수이다.메서드 사용
이렇게 선언된 메서드는 어떻게 사용할까?public class Main {
public static void main(String[] args) {
this.stats(3, 5, 10); // this.메서드이름(실제매개변수값1, 실제매개변수값2, ..)
stats(3, 5, 10); // 또는 그냥 메서드이름(실제매개변수값1, 실제매개변수값2, ..)
}
void stats(int a, int b, int c) {
//재사용 할 코드
}
}메서드는 위처럼 this.메서드 이름, 또는 그냥 메서드 이름으로 접근 할 수 있다. 둘 사이의 차이점은 없으면 this는 이후에 자바의 객체지향프로그래밍 특징들을 설명하며 다시 다룰 예정이다. 여기서 중요한건 어떤 함수는 마침표(.)을 이용해 접근 할 수 있다는 뜻이다. 위 코드를 복사 붙여넣기 하면 컴파일 에러가 날 것이다. 이는 main의 특성 때문이므로 지금은 아래처럼 고쳐주도록 하자. static이 무엇인지는 이후에 설명하도록 하겠다.public class Main {
public static void main(String[] args) {
stats(3, 5, 10);
}
static void stats(int a, int b, int c) {
System.out.println("넘어온 매개변수 ? " + a + " " + b + " " + c);
}
} 실행 결과: 넘어온 매개변수 ? 3 5 10stats을 두번 부른 메서드를 실행 해보자.
public class Main {
public static void main(String[] args) {
stats(3, 5, 10);
stats(13, 5, 10);
}
static void stats(int a, int b, int c) {
System.out.println("넘어온 매개변수 ? " + a + " " + b + " " + c);
}
}
실행 결과: 넘어온 매개변수 ? 3 5 10 넘어온 매개변수 ? 13 5 10이를 통해 매개변수로 넘기는 3, 5, 10이 a, b, c에 제대로 들어가는 것을 확인 할 수 있다. 그러면 이제 원래 목표였던 통계 값 출력을 해 보도록 하자. 반복되는 코드였던 부분을 복사 붙여넣기 한 후 변수 이름으 a, b, c로 고쳐주면 된다. x, y, z로 하면 헷갈릴것 같아서 a, b, c로 한 것이다.
public class Main {
public static void main(String[] args) {
stats(3, 5, 10);
stats(13, 5, 10);
}
static void stats(int a, int b, int c) {
int min = a;
if (min > b) {
min = b;
}
if (min > c) {
min = c;
}
int max = a;
if(max < b) {
max = b;
}
if(max < c) {
max = c;
}
int s = (a + b + c);
int avg = (a + b + c)/3;
System.out.println("합 : " + s);
System.out.println("평균 : " + avg );
System.out.println("최솟값 : " + min);
System.out.println("최댓값 :" + max);
}
}
실행 결과: 합 : 18 평균 : 6 최솟값 : 3 최댓값 :10 합 : 28 평균 : 9 최솟값 : 5 최댓값 :10이제 stats내부의 코드를 main안에서 여러번 반복 할 필요 없이 stats라는 메서드를 부르고 원하는 매개변수를 넘겨주기만 하면 원하는 통계값을 계속해서 얻을 수 있다.
연습문제
자 이제 더 나아가 stat에 있는 코드들도 나눠보자. 한 메서드가 여러가지 일을 하는 것은 소프트웨어 디자인 측면에서 보면 좋지 못하다. 현재 stats이라는 메서드는 4가지 기능을 하고 있다. 합, 평균, 최솟값, 최댓값. 이 네개의 기능을 각각 따로따로 나누는 메서드를 만들어보자. 그리고 stats에서는 출력만 하도록 하자. 무슨 뜻이냐면 예를들어서,
public class Main {
public static void main(String[] args) {
stats(3, 5, 10);
stats(13, 5, 10);
}
static void stats(int a, int b, int c) {
int min = a;
if (min > b) {
min = b;
}
if (min > c) {
min = c;
}
int max = a;
if(max < b) {
max = b;
}
if(max < c) {
max = c;
}
int s = sum(a, b, c);
int avg = (a + b + c)/3;
System.out.println("합 : " + s);
System.out.println("평균 : " + avg);
System.out.println("최솟값 : " + min);
System.out.println("최댓값 :" + max);
}
static int sum(int x, int y, int z) {
return x + y + z;
}
}우리는 합을 (a + b + c)하는 대신에 sum이라는 메서드를 만들어 리턴 할 수 있다. 이 sum이라는 메서드는 넘어온 세 개의 매개변수를 모두 더한 값을 리턴한다. 리턴된 값을 저장하기 위해 이 메서드를 부르는 stats메서드에 int s라는 변수를 선언하고 반환된 함수의 값을 집어넣도록(할당) 하자. 마찬가지의 방법으로 나머지 3개의 기능을 위한 메서드를 만들고 stats에서 콜 하도록 해보자.
코드가 실행되는 과정
메서드를 포함하는 코드가 실행되는 과정은 다음과 같다. 일단 메서드 콜이 시작되면 실행되던 코드는 매개변수를 가지고 해당 메서드가 있는 부분으로 점프한다. 이후 해당 메서드를 실행 후 다시 원래 부분이었던 메서드를 부른 부분으로 돌아간다. 따라서 위의 코드는 , 1 -> 2-> 3-> 4-> 5-> 6의 순서로 진행된다.
메인 메서드
이제 기본으로 메서드에 대해 배웠으니 main에 대해 알아보자.
public class Main {
public static void main(String[] args) {
}
}메인 메서드는 어떻게 생겼는가? public static void main(String[] args){ .. } 이렇게 생겼다. 맨 처음 자바 공부를 시작 했을 때, 메인이라는 것은 프로그램이 시작되면 가장 먼저 불린다고 했다. 가장 먼저 콜되는 메서드이다. 메인은 메서드이므로 리턴 값 void 메서드 이름 main, 매개변수 (String[] args)로 선언된다. public static은 나중에 설명 할 것이니 잠시 넘어가도록 하자. 메인 메서드는 항상 public static void main(String[] args)으로 시작하고 이렇게 써야만 자바가 프로그램을 실행 할 때 어디서부터 시작 할 지 알 수 있다. 따라서, 위에서 메서드를 '재사용 가능한 가장 작은 코드의 단위'라고 설명 한 것이다. 여러분은 메서드가 뭔지 모르면서도 메인 메서드 하나를 사용하고 있었으니 말이다.
System.out.println()
우리가 모르고 사용한 메서드가 하나 더 있다. 바로 System.out.println이라는 메서드이다. 위에서 this.stats으로 .을 이용해 메서드에 접근 할 수 있다고 했다. this는 쉽게 말해 현재 클래스(class라고 써있는 부분) 내부의 메서드를 부른다는 뜻이다. 그렇다면 System.out.println이란 무엇인가? 잘은 모르겠지만 System.out이라는곳에 존재하는 println이라는 메서드를 사용하겠다는 뜻이다. 그리고 우리는 매개변수로 뭘 넘겨줬는가? "평균 : " + s과 같은 쌍따옴표로 표현된 문자열을 넘겨주었다.
메서드를 사용하는 이유
메서드는 왜 사용하는가? 첫번째 이유는 재사용성 때문이다. 반복되는 코드를 메서드로 만들어 반복해서 사용한다면 코드의 크기를 줄이고 가독성을 높일 수 있다. 꼭 코드가 반복되지 않더라도 너무 큰 코드는 메서드로 작성하여 간결하게, 가독성이 높게 만들 수 있다. 다음으로는 추상화의 목적이 있다. 예를들어 여러분이 어떤 메서드를 만들어 놓으면 다른사람은 그 메서드의 내부를 구현 할 필요가 없고, 이해 할 필요도 없다. 그냥 갖다 쓰면 된다. 마치 여러분이 System.out.println의 구현을 모른 채로 그냥 갖다 썼던 것 처럼 말이다.
끝
이번 포스트를 통해서 자바의 메서드를 알아보았다. 다음 포스트에서 드디어! 클래스에 대해 알아보도록 하겠다.
'자바(Java) 강의' 카테고리의 다른 글
6. 자바 오브젝트와 클래스 (2) 클래스 (3) 2019.03.29 6. 자바 오브젝트와 클래스 (1) built-in 오브젝트 (1) 2019.03.26 4. 자바 배열과 반복문 (5) while (0) 2019.03.24 4. 자바 배열과 반복문 (4) 연습 - 배열의 최댓값 구하기 (11) 2019.03.17 4. 자바 배열과 반복문 (4) 중첩 반복문 (0) 2019.03.14 댓글