Skip to content

Latest commit

 

History

History
229 lines (182 loc) · 12.5 KB

File metadata and controls

229 lines (182 loc) · 12.5 KB

메서드

함수

함수 정의

add(a, b) = a + b

  • 이름이 add이고, a, b 라는 두 값을 받는 함수이다. 그리고 이 함수는 a + b 연산을 수행한다.

함수 사용

  • 함수에 값을 입력하면, 함수가 가진 연산을 처리한 다음 결과를 출력한다. 여기서는 단수히 a+b라는 연산을 수행한다.
  • 여러번 같은 계산을 해야 한다면 지금처럼 함수를 만들어두고(정의), 필요한 입력 값을 넣어서 해당 함수를 호출하면 된다. 그러면 계산된 결과가 나온다.
  • 함수는 마치 블랙박스와 같다. 함수를 호출할 때는 외부에서는 필요한 값만 입력하면 된다. 그러면 계산된 결과가 출력된다.
  • 같은 함수를 다른 입력 값으로 여러번 호출할 수 있다.
  • 여기서 핵심은 함수를 한번 정의해두면 계속해서 재사용할 수 있다는 점이다!

메서드 사용

public class Method1Ref {
    public static void main(String[] args) {
        int sum1 = add(5, 10);
        System.out.println("결과1 출력 : " + sum1);
        System.out.println("=============================");

        int sum2 = add (15, 20);
        System.out.println("결과2 출력 : " + sum2);
    }
    // add 메서드
    public static int add(int a, int b) {
        System.out.println(a + " + " + b + " 연산 수행 ");

        return a + b;
    }
}

위 코드 중

 public static int add(int a, int b) {
        System.out.println(a + " + " + b + " 연산 수행 ");

        return a + b;
    }

이 부분이 바로 메서드이다. 이것을 함수를 정의하는 것과 같이, 메서드를 정의한다고 표현한다. 메서드는 수학의 함수와 유사하게 생겼다. 함수에 값을 입력하면 ,어떤 연산을 처리한 다음에 결과를 반환한다.

메서드는 크게 메서드 선안과 메서드 본문으로 나눌 수 있다.

메서드 선언

pulic static int add(int a, int b)

메서드의 선언 부분으로서, 메서드 이름, 반환 타입, 매개변수(파라미터)목록을 포함한다. 이름 그대로 이런 메서드가 있다고 선언하는 것이다. 메서드 선언 정보를 통해 다른 곳에서 해당 메서드를 호출할 수 있다.

  • public static

    • public : 다른 클래스에서 호출할 수 있는 메서드라는 뜻이다.
    • static : 객체를 생성하지 않고 호출할 수 있는 정적 메서드라는 뜻이다.
  • int add (int a, int b)

    • int : 봔한 타입을 정의한다. 메서드의 실행 결과를 반환할 떄 사용할 반환 타입을 지정한다.
    • add : 메서드에 이름을 부여한다. 이 이름으로 메서드를 호출할 수 있다.
    • (int a, int b) : 메서드를 호출할 때 전달하는 입력 값을 정의한다. 이 변수들은 해당 메서드 안에서만 사용된다. 이렇게 메서드 선언에 사용되는 변수를 영어로 파라미터(parameter), 한글로 매개변수 라고 한다.

메서드 본문(Method Body)

 {
        System.out.println(a + " + " + b + " 연산 수행 ");

        return a + b;
    }
  • 메서드가 수행해야 하는 코드 블록이다.
  • 메서드를 호출하면 메서드 본문이 순서대로 실행된다.
  • 메서드 본문은 블랙박스이다. 메서드를 호출하는 곳에서는 메서드 선언은 알지만 메서드 본문은 모른다.
  • 메서드의 실행 결과를 반환하려면 return문을 사용해야 한다. return문 다음에 반환할 결과를 적어주면 된다.
    • return sum : sum 변수에 들어있는 값을 반환한다.

메서드 호출과 용어 정리

매서드를 호출할 때는 다음과 같이 메서드에 넘기는 값과 매개변수(파라미터)의 타입이 맞아야 한다. 물론 넘기는 값과 매개변수(파라미터)의 순서와 갯수도 맞아야 한다.

호출 : call("hello", 20)

메서드 정의 : int call (String str, int age)

인수 (Argument)

여기서 "hello", 20처럼 넘기는 값을 영어로 Argument(아규먼트), 한글로 인수 또는 인자라 한다. 실무에서는 아규먼트, 인수, 인자라는 용어를 모두 사용한다.

매개변수(Parameter)

메서드를 정의할 때 선언한 변수인 String str, int age를 매개변수, 파라미터라 한다. 메서드를 호출할 때 인수를 넘기면, 그 인수가 매개변수에 대입된다. 실무에서는 매개변수, 파라미터 용어를 모두 사용한다.

용어정리

  • 인수라는 용어는 '인'과 '수'의 합성어로, '들어가는 수'라는 의미를 가진다. 즉, 메서드 내부로 들어가는 값을 의미한다. 인자도 같은 의미이다.
  • 매개변수, parameter는 '매개'와 '변수'의 합성어로, '중간에서 전달하는 변수'라는 의미를 가진다. 즉, 메서드 호출부와 메서드 내부 사이에서 값을 전달하는 역할을 하는 변수라는 뜻이다.

메서드 정의

메서드는 다음과 같이 정의한다.

    public static int add(int a, int b) {
    // 메서드 본문, 실행 코드
    }
    
    제어자 반화타입 메서드이름(매개변수 목록) {
        메서드 본문
    }   
  • 제어자(Modifier) : public, static과 같은 부분이다.
  • 반환 타입(Return Type) : 메서드가 실행 된 후 반환하는 데이터의 타입을 지정한다. 메서드가 값을 반환하지 않는 경우, 없다는 뜻의 void를 사용해야 한다. 예) void print(String str)
  • 메서드 이름(Method Name) : 메서드의 이름이다. 이 이름은 메서드를 호출하는데 사용된다.
  • 매개변수(Parameter) : 입력 값으로, 메서드 내부에서 사용할 수 있는 변수이다. 매개변수는 옵션이다. 입력값이 필요 없는 메서드는 매개변수를 지정하지 않아도 된다. 예) add()
  • 메서드 본문(Method Body) : 실제 메서드의 코드가 위치한다. 중괄호 { } 사이에 코드를 작성한다.

메서드 오버로딩

자바는 메서드의 이름 뿐만 아니라 매개변수 정보를 함께 사용해서 메서드를 구분한다.

  • 오버로딩 성공
add (int a, int b)
add (int a, int b, int c)
add (double a, double b)
  • 오버로딩 규칙

메서드의 이름이 같아도 매개변수의 타입 및 순서가 다르면 오버로딩을 할 수 있다. 참고로 반환 타입은 인정하지 않는다.

  • 오버로딩 실패
int add(int a, int b)
double add(int a, int b)

용어 : 메서드 시그니처(method signature)

메서드 시그니처 = 메서드 이름 + 매개변수 타입(순서)

메서드 시그니처는 자바에서 메서드를 구분할 수 있는 고유한 식별자나 서명을 듯한다. 메서드 시그니처는 메서드의 이름과 매개변수 타입(순서 포함)으로 구성되어 있다. 쉽게 이야기해서 메서드를 구분할 수 있는 기준이다. 자바 입장에서는 각각의 매서드를 고유하게 구분할 수 있어야 한다. 그래야 어떤 메서드를 호출 할 지 결정할 수 있다. 따라서 메서드 오버로딩에서 설명한 것처럼 메서드 이름이 같아도 메서드 시그니처가 다르면 다른 메서드로 간주한다. 반환 타입은 시그니처에 포함되지 않는다. 방금 오버로딩이 실패한 두 메서드를 보자. 두 메서드는 add(int a, int b)로 메서드 시그니처가 같다. 따라서 메서드의 구분이 불가능하므로 컴파일 오류가 발생한다.

좋은 코딩

public class MethodEx4Ref {
    public static void main(String[] args) {
        int balance = 0;
        Scanner scanner = new Scanner(System.in);

        while(true) {
            System.out.println("----------------------------------");
            System.out.println("1.입금 | 2. 출금 | 3. 잔액확인 | 4. 종료");
            System.out.println("----------------------------------");
            System.out.print("선택 : ");

            int choice =  scanner.nextInt();
            int amount;

            switch (choice) {
                case 1:
                    System.out.print("입금액을 입력하세요 : ");
                    amount = scanner.nextInt();
                    balance = deposit(balance, amount);
                    break;
                case 2:
                    System.out.print("총 금액을 입력하세요 : ");
                    amount = scanner.nextInt();
                    balance = withdraw(balance, amount);
                    break;
                case 3:
                    System.out.println("현재 잔액 : " + balance + "원");
                    break;
                case 4:
                    System.out.println("시스템을 종료합니다.");
                    return;
                default:
                    System.out.println("올바른 선택이 아닙니다. 다시 선택해주세요.");
                    break;
            }
        }

    }
    public static int deposit(int balance, int amount) {
        balance += amount;
        System.out.println(amount + "원을 입금하셨습니다. 현재 잔액 : " + balance + "입니다.");
        return balance;
    }

    public static int withdraw(int balance, int withdrawAmount) {

        if (balance >= withdrawAmount) {
            balance -= withdrawAmount;
            System.out.println(withdrawAmount + "원을 송금하셨습니다.. 현재 잔액: " + balance + "원");
            return balance;
        }

        else {
            System.out.println(withdrawAmount + "원을 송금하려 했으나 잔액이 부족합니다.");
            return balance;
        }

    } 

리펙토링 결과물을 보면 main()은 세세한 코드가 아니라 전체 구조를 한눈에 볼 수 있게 되었다. 쉽게 이야기해서 책의 목찰르 보는 것 같다. 더 자세히 알고 싶으면 해당 메서드를 찾아서 들어가면 된다. 그리고 입금과 출금 부분이 메서드로 명확하게 분리되었기 때문에 이후에 변경 사항이 발생하면 관련된 메서드만 수정하면 된다. 특정 메서드로 수정 범위가 한정되기 때문에 더 유지보수 하기 좋다. 이런 리펙토링을 메서드 추출(Extract Method)이라 한다. 메서드를 재사용하는 목적이 아니어도 갠찮다. 메서드를 적절하게 사용해서 분류하면 구조적으로 읽기 쉽고 유지보수 하기 좋은 코드를 만들 수 있다. 그리고 메서드의 이름 덕분에 프로그램을 더 읽기 좋게 만들 수 있다.

정리

변수명 vs 메서드명

변수 이름은 일반적으로 명사를 사용한다. 한편 메서드는 무언가 동작하는데 사용하기 때문에 일반적으로 동사로 시작한다. 이런 차이점 외에는 변수 이름과 메서드 이름에 규칙은 둘 다 같다.

  • 변수명 예) : customerName, totalSum, employeeCount, isAvailable
  • 메서드명 예) : printReport(), calculateSum(), addCustomer(), getEmployeeCount(), setEmployeeName()

메서드 사용의 장점

  • 코드 재사용 : 메서드는 특정 기능을 캡슐화하므로, 필요할 때마다 그 기능을 다시 작성할 필요 없이 해당 메서드를 호출함으로써 코드를 재사용 할 수 있다.
  • 코드의 가독성 : 이름이 부여된 메서드는 코드가 수행하는 작업을 명확하게 나타내므로, 코드를 읽는 사람에게 추가적인 문맥을 제공한다.
  • 모듈성 : 큰 프로그램을 작은, 관리 가능한 부분으로 나눌 수 있다. 이는 코드의 가독성을 향상시키고 디버깅을 쉽게 만든다.
  • 코드 유지 관리 : 메서드를 사용하면, 코드의 특정 부분에서 문제가 발생하거나 업데이트가 필요한 경우 해당 메서드만 수정하면 된다. 이렇게 하면 전체 코드 베이스에 영향을 주지 않고 변경 사항을 적용할 수 있다.
  • 재사용성과 확장성 : 잘 설계된 메서드는 다른 프로그램이나 프로젝트에서도 재사용할 수 있으며 새로운 기능을 추가하거나 기존 기능을 확장하는 데 유용하다.
  • 추상화 : 메서드를 사용하는 곳에서는 메서드의 구현을 몰라도 된다. 프로그램의 다른 부분에서는 복잡한 내ㅁ부 작업에 대해 알 필요 없이 메서드를 사용할 수 있다.
  • 테스트와 디버깅 용이성 : 개별 메서드는 독립적으로 테스트하고 디버그 할 수 있다. 이는 코드의 문제를 신속하게 찾고 수정하는 데 도움이 된다.

따라서, 메서드는 효율적이고 유지 보수가 가능한 코드를 작성하는 데 매우 중요한 도구이다.