본문 바로가기
IT/김영한의JAVA입문_inFlearn

9. 메서드 - 메서드 시작 / 메서드 사용 / 메서드 정의 / 반환 타입 / 메서드 호출과 값 전달 1~2 / 메서드와 형변환 / 메서드 오버로딩 / 문제와 풀이 1~2

by for-learn 2025. 1. 23.

9-1. 메서드 시작

Method1.java

package method;

public class Method1 {
    public static void main(String[] args) {
        // 계산1
        int a = 1;
        int b = 2;
        System.out.println(a + "+" + b + " 연산 수행");
        int sum1 = a + b;
        System.out.println("결과1 출력:" + sum1);

        // 계산2
        int x = 10;
        int y = 20;
        System.out.println(x + "+" + y + " 연산 수행");
        int sum2 = x + y;
        System.out.println("결과2 출력:" + sum2);
    }
}
  • 같은 연산을 두번 수행

  • 수학의 함수 개념을 차용해서 사용
  • 함수를 한번 정의해두면 재사용이 가능
  • 필요할 때마다 함수명으로 호출해서 사용

 

9-2. 메서드 사용

메서드(Method)는 함수의 한 종류

Method1.java

package method;

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

        // 계산2
        int sum2 = add(15, 20);
        System.out.println("결과2 출력:" + sum2);
    }

    // add 메서드
    public static int add(int a, int b) {
        System.out.println(a + "+" + b + " 연산 수행");
        int sum = a + b;
        return sum;
    }
}

 

- 메서드 정의 (메서드를 정의한다)

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

 

- 메서드 선언(Method Declaration)

public 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 + " 연산 수행");
    int sum = a + b;
    return sum;
}
  • 메서드를 호출하면 메서드 본문이 순서대로 실행
  • 메서드 본문은 블랙박스 => 메서드를 호출하는 곳에서는 메서드 선언은 알지만 메서드 본문은 모름
  • 메서드 실행 결과를 반환하려면 return문을 사용

- 메서드 호출

int sum1 = add(5, 10);
/*
public static int add(5, 10){
    int sum = 5 + 10;
    return sum(15);
*/

int sum2 = add(15, 20);
/*
public static int add(15, 20){
    int sum = 15 + 20;
    return sum(35);
*/
  • 메서드 호출이 끝나면 더 이상 해당 메서드가 사용한 메모리를 낭비할 이유가 없기 때문에, 파라미터 변수메서드 안에서 정의된 int sum 모두 제거된다. 

- 메서드 호출과 용어 정리

호출: call("hello", 20) // 인수, 인자
메서드 정의: int call(String str, int age) // 매개변수, 파라미터

메서드 호출할 때,

  • 메서드에 넘기는 값매개변수(파라미터)의 타입이 맞아야 한다. 
  • 또, 매개변수(파라미터)의 순서와 갯수도 맞아야 한다. 

인자 = 인수(Argument)

  • "hello", 20 처럼 메서드에 넘기는 값
  • ''과 ''의 합성어로 '들어가는 수'라는 의미 => 메서드 내부로 들어가는 값

매개변수(Parameter)

  • 메서드를 정의할 때 선언한 변수 => String str, int age
  • '매개'와 '변수'의 합성어로  '중간에서 전달하는 변수'라는 의미 => 메서드 호출부메서드 내부 사이에서 값을 전달하는 역할을 하는 변수

 

9-3. 메서드 정의

public static int add(int a, int b) {
    // 메서드 본문, 실행 코드
}

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

 

Method2.java - 매개변수가 없거나 반환타입이 없는 경우

package method;

public class Method2 {
    public static void main(String[] args) {
        printHeader(); // 인수를 비워두고 호출
        System.out.println("프로그램이 동작합니다.");
        printFooter(); // 반환 타입이 없으므로 반환 값을 받으면 안됨
    }

    public static void printHeader() { // 매개변수를 비워두고 정의
        System.out.println("= 프로그램을 시작합니다 =");
        return; // void의 경우 생략 가능
    }

    public static void printFooter() { // 반환 타입이 없으면 void로 정의
        System.out.println("= 프로그램을 종료합니다 =");
    }
}

  • return을 만나면 해당 메서드는 종료된다. 

 

9-4. 반환 타입

MethodReturn1.java - 반환 타입이 있으면 반드시 return을 사용해서 값을 반환해야 한다. 

package method;

public class MethodReturn1 {
    public static void main(String[] args) {
        boolean result = odd(2);
        System.out.println(result);
    }

    public static boolean odd(int i) {
        if (i % 2 == 1) {
            return true;
        } else {
            return false;
        }
    }
}

 

MethodReturn2.java - return문을 만나면 그 즉시 메서드를 종료한다. 

package method;

public class MethodReturn2 {
    public static void main(String[] args) {
        checkAge(10);
        checkAge(20);
    }
    public static void checkAge(int age) {
        if (age < 18) {
            System.out.println(age + "살, 미성년자는 출입이 불가능합니다.");
            return; // 메서드를 빠져나간다.
        }
        System.out.println(age + "살, 입장하세요.");
    }
}

 

9-5. 메서드 호출과 값 전달1

"자바는 항상 변수의 값을 복사해서 대입한다. "

MethodValue0.java - 변수와 값 복사

package method;

public class MethodValue0 {
    public static void main(String[] args) {
        int num1 = 5;
        int num2 = num1;
        num2 = 10;
        System.out.println("num1=" + num1);
        System.out.println("num2=" + num2);
    }
}

MethodValue1.java - 메소드 호출과 값 복사

package method;

public class MethodValue1 {
    public static void main(String[] args) {
        int num1 = 5;
        System.out.println("1. changeNumber 호출 전, num1: " + num1);
        changeNumber(num1);
        System.out.println("4. changeNumber 호출 후, num1: " + num1);
    }

    public static void changeNumber(int num2) {
        System.out.println("2. changeNumber 변경 전, num2: " + num2);
        num2 = num2 * 2;
        System.out.println("3. changeNumber 변경 후, num2: " + num2);
    }
}

 

9-6. 메서드 호출과 값 전달2

MethodValue2.java - 메소드 호출과 이름이 같은 변수

package method;

public class MethodValue2 {
    public static void main(String[] args) {
        int number = 5;
        System.out.println("1. changeNumber 호출 전, number: " + number);
        changeNumber(number);
        System.out.println("4. changeNumber 호출 후, number: " + number);
    }
    public static void changeNumber(int number) {
        System.out.println("2. changeNumber 변경 전, number: " + number);
        number = number * 2;
        System.out.println("3. changeNumber 변경 후, number: " + number); 
    }
}

  • main()도 사실은 메서드
  • 각각의 메서드 안에서 사용하는 변수는 서로 완전히 분리된 다른 변수이다. (이름이 같아도)

MethodValue3.java - 메소드 호출과 값 반환받기

package method;

public class MethodValue3 {
    public static void main(String[] args) {
        int num1 = 5;
        System.out.println("changeNumber 호출 전, num1: " + num1); // 출력: 5
        num1 = changeNumber(num1); // 값 반환
        System.out.println("changeNumber 호출 후, num1: " + num1); // 출력: 10
    }
    
    public static int changeNumber(int num2) {
        num2 = num2 * 2;
        return num2;
    }
}

 

9-7. 메서드와 형변환

MethodCasting1.java - 명시적 형변환

메서드를 호출하는데 인자와 매개변수의 타입이 맞지 않을 때, 

package method;

public class MethodCasting1 {
    public static void main(String[] args) {
        double number = 1.5;
        // printNumber(number); // double을 int로 대입하므로 컴파일 오류
        // 오류 => java: incompatible types: possible lossy conversion from double to int
        printNumber((int) number); // 명시적 형변환을 사용해 double을 int로 변환
    }

    public static void printNumber(int n) {
        System.out.println("숫자: " + n);
    }
}

 

MethodCasting2.java - 자동 형변환

int < long < double

package method;

public class MethodCasting2 {
    public static void main(String[] args) {
        int number = 100;
        printNumber(number);
    }

    public static void printNumber(double n) {
        System.out.println("숫자: " + n); // 숫자: 100.0
    }
}
  • double형 매개변수(파라미터)int형 인수를 전달하는데 문제없이 잘 동작

 

9-8. 메서드 오버로딩

다음과 같은 메서드를 같은 이름인 add로 만들고 싶다. 

  • 두 수를 더하는 메서드
  • 세 수를 더하는 메서드

 

오버로딩 성공

add(int a, int b)
add(int a, int b, int c)
add(double a, double b)
add(int a, double b) // 매개변수의 
add(double a, int b) //  순서가 다름
  • 메서드 오버로딩(Overloading) : 매개변수가 다르고 같은 이름의 메서드를 여러개 정의하는 것.
    과적(과하게 물건을 담았다.)

 

오버로딩 규칙

  • 메서드 이름이 같아도, 매개변수의 타입 및 순서가 다르면 오버로딩 가능. 반환 타입은 인정하지 않음

 

오버로딩 실패

int add(int a, int b)
double add(int a, int b)

 

 

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

  • 메서드 시그니처 = 메서드 이름 + 매개변수 타입(순서)
  • 자바에서 메서드를 구분할 수 있는 고유한 식별자나 서명을 뜻한다.
  • 메서드 이름이 같아도 메서드 시그니처가 다르면 다른 메서드로 간주
  • 반환 타입은 시그니처에 포함되지 않는다. 

Overloading1.java 

package method;

public class Overloading1 {
    public static void main(String[] args) {
        System.out.println("1: " + add(1, 2));
        System.out.println("2: " + add(1, 2, 3));
    }

    // 첫 번째 add 메서드: 두 정수를 받아서 합을 반환한다.
    public static int add(int a, int b) {
        System.out.println("1번 호출");
        return a + b;
    }

    // 두 번째 add 메서드: 세 정수를 받아서 합을 반환한다.
    // 첫 번째 메서드와 이름은 같지만, 매개변수 목록이 다르다.
    public static int add(int a, int b, int c) {
        System.out.println("2번 호출");
        return a + b + c;
    }
}

Overloading2.java

package method;

public class Overloading2 {
    public static void main(String[] args) {
        myMethod(1, 1.2);
        myMethod(1.2, 2);
    }

    public static void myMethod(int a, double b) {
        System.out.println("int a, double b");
    }

    public static void myMethod(double a, int b) {
        System.out.println("double a, int b");
    }
}

Overloading3.java

package method;

public class Overloading3 {
    public static void main(String[] args) {
        System.out.println("1: " + add(1, 2));
        System.out.println("2: " + add(1.2, 1.5));
    }

    // 첫 번째 add 메서드: 두 정수를 받아서 합을 반환한다.
    public static int add(int a, int b) {
        System.out.println("1번 호출");
        return a + b;
    }

    // 두 번째 add 메서드: 두 실수를 받아서 합을 반환한다.
    // 첫 번째 메서드와 이름은 같지만, 매개변수의 유형이 다르다.
    public static double add(double a, double b) {
        System.out.println("2번 호출");
        return a + b;
    }
}
  • 첫번재 add 메서드가 없으면 자동 형변환 발생해 add(double a, double b)가 호출된다.

 

메서드 사용의 장점

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

 

9-9. 문제와 풀이1

MethodEx1.java

package method.ex;

public class MethodEx1 {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        int c = 3;

        int sum = a + b + c;
        double average = sum / 3.0;
        System.out.println("평균값: " + average);

        int x = 15;
        int y = 25;
        int z = 35;

        sum = x + y + z;
        average = sum / 3.0;
        System.out.println("평균값: " + average);
    }
}

 

MethodEx1Ref.java

package method.ex;

public class MethodEx1Ref {
    public static void main(String[] args) {
        System.out.println("평균값: " + average(1, 2, 3));
        System.out.println("평균값: " + average(15, 25, 35));
    }

    public static double average(int a, int b, int c) {
        int sum = a + b + c;
        return sum / 3.0;
    }
}

 

MethodEx2.java

package method.ex;

public class MethodEx2 {
    public static void main(String[] args) {
        String message = "Hello, world!";
        for (int i = 0; i < 3; i++) {
            System.out.println(message);
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(message);
        }
        for (int i = 0; i < 7; i++) {
            System.out.println(message);
        }
    }
}

 

MethodEx2Ref.java

package method.ex;

public class MethodEx2Ref {
    public static void main(String[] args) {
        repeat(3); // repeat("Hello, world!", 3);
        repeat(5);
        repeat(7);
    }

    public static void repeat(int n) {
        System.out.println(n+"번 반복");
        for (int i = 0; i < n; i++) {
            System.out.println("Hello, world!");
        }
    }
}

 

MethodEx3.java

package method.ex;

public class MethodEx3 {
    public static void main(String[] args) {
        int balance = 10000;

        // 입금 1000
        int depositAmount = 1000;
        balance += depositAmount;
        System.out.println(depositAmount + "원을 입금하였습니다. 현재 잔액: " + balance + "원");

        // 출금 2000
        int withdrawAmount = 2000;
        if (balance >= withdrawAmount) {
            balance -= withdrawAmount;
            System.out.println(withdrawAmount + "원을 출금하였습니다. 현재 잔액: " + balance + "원");
        } else {
            System.out.println(withdrawAmount + "원을 출금하려 했으나 잔액이 부족합니다.");
        }

        System.out.println("최종 잔액: " + balance + "원");
    }
}

MethodEx3Ref.java

package method.ex;

public class MethodEx3Ref {
    public static void main(String[] args) {
        int balance = 10000;

        balance = deposit(balance, 1000);
        balance =  withdraw(balance, 2000);

        System.out.println("최종 잔액: " + balance + "원");
    }

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

        return balance;
    }

    public static int withdraw(int balance, int amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println(amount + "원을 출금하였습니다. 현재 잔액: " + balance + "원");
        } else {
            System.out.println(amount + "원을 출금하려 했으나 잔액이 부족합니다.");
        }
        return balance;
    }
}

 

9-10. 문제와 풀이2

MethodEx4.java

package method.ex;

import java.util.Scanner;

public class MethodEx4 {
    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 option = scanner.nextInt();
            if (option == 1){
                System.out.print("입금액을 입력하세요: ");
                int amount = scanner.nextInt();
                balance = deposit(balance, amount);
            } else if (option == 2) {
                System.out.print("출금액을 입력하세요: ");
                int amount = scanner.nextInt();
                balance = withdraw(balance, amount);
            } else if (option == 3) {
                System.out.println("현재 잔액: " + balance + "원");
            } else if (option == 4) {
                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 amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println(amount + "을 출금했습니다. 현재 잔액: " + balance);
        } else {
            System.out.println(amount + "을 출금하려 했으나 잔액이 부족합니다.");
        }
        return balance;
    }
}

 

강의 풀이 => switch문을 사용

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("올바른 선택이 아닙니다. 다시 선택해주세요.");
        }
    }