ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 5. 자바 메서드
    자바(Java) 강의 2019. 3. 25. 11:55

    배열과 반복문을 통해 우리는 어떻게 하면 반복적으로 나타나는 코드를 간결하게 줄일 수 있는지 알아보았다. 하지만 때로는 반복문이 모든걸 해결 해 주지 않는다. 이번 포스트에서는 자바의 메서드가 어떤 문제를 해결하는지, 왜 사용하는지, 그리고 어떻게 사용하는지에 대해 알아보도록 하겠다.

    예상 독자

    목표

    • 메서드 (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 10

    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) {
    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의 구현을 모른 채로 그냥 갖다 썼던 것 처럼 말이다.

    이번 포스트를 통해서 자바의 메서드를 알아보았다. 다음 포스트에서 드디어! 클래스에 대해 알아보도록 하겠다.

    다음 포스트: 6. 자바 오브젝트와 클래스 (1) built-in 오브젝트

    댓글

f.software engineer @ All Right Reserved