9장 메서드
Updated:
메서드
자바에서는 함수를 메서드(Method)라 한다. 메서드도 함수의 한 종류하고 생각하면 된다. 다음 코드를 보자.
package method;
public class Method1Ref {
public static void main(String[] args) {
int sum1 = add(5, 10);
System.out.println("결과1 출력: " + sum1);
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;
}
}
메서드는 크게 메서드 선언과 메서드 본문으로 나눌 수 있다.
- 메서드 선언(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)
- 메서드가 수행해야 하는 코드 블록이다.
- 메서드를 호출하면 메서드 본문이 순서대로 실행된다.
- 메서드의 실행 결과를 반환하여면 return문을 사용해야 한다.
메서드 호출과 용어정리
메서드를 호출할 때는 다음과 같이 메서드에 넘기는 값과 매개변수(파라미터)의 타입이 맞아야 한다. 물론 넘기는 값과 매개변수(파라미터)의 순서와 갯수도 맞아야 한다.
호출: call("hello", 20)
메서드 정의: int call(String str, int age)
- 인수(Argument)
- “hello”, 20처럼 넘기는 값을 영어로 Argument(아규먼트), 한글로 인수 또는 인자라 한다.
- 매개변수(Parameter)
- String str, int age를 매개변수, 파라미터라 한다. 메서드를 호출할 때 인수를 넘기면, 그 인수가 매개변수에 대입된다.
메서드 정의
메서드는 다음과 같이 정의한다.
public static int add(int a, int b) {
// 메서드 본문, 실행 코드
}
/*
제어자 반화타입 메서드이름(매개변수 목록) {
메서드 본문
}
*/
- 제어자(Modifier): public, static과 같은 부분이다.
- 반환 타입(Return Type): 메서드가 실행 된 후 반환하는 데이터의 타입을 지정한다. 메서드가 값을 반환하지 않을 경우, void를 사용해야 한다.
- 메서드 이름(Method Name): 메서드를 호출하는 데 사용된다.
- 매개변수(Parameter): 입력 값으로, 메서드 내부에서 사용할 수 있는 부분이다. 매개변수는 옵션이다. 입력값이 필요 없는 메서드는 매개변수를 지정하지 않아도 된다.
- 메서드 본문(Method Body): 실제 메서드의 코드가 위치한다. 중괄호 {}사이에 코드를 작성한다.
메서드 사용의 장점
- 코드 재사용: 메서드는 특정 기능을 캡슐화하므로, 필요할 때마다 그 기능을 다시 작성할 필요 없이 해당 메서드를 호출함으로써 코드는 재사용할 수 있다.
- 코드의 가독성: 이름이 부여된 메서드는 코드가 수행하는 작업을 명확하게 나타내므로, 코드를 읽는 사람에게 추가적인 문맥을 제공한다.
- 모듈성: 큰 프로그램을 작음, 관리 가능한 부분으로 나눌 수 있다. 이는 코드의 가독성을 향상시키고 디버깅을 쉽게 만든다.
- 코드 유지 관리: 메서드를 사용하면, 코드와 특정 부분에서 문제가 발생하거나 업데이트가 필요한 경우 해당 메서드만 수정하면 된다. 이렇게 하면 전체 코드 베이스에 영향을 주지 않고 변경 사항을 적용할 수 있다.
- 재사용성과 확장성: 잘 설계된 메서드는 다른 프로그램이나 프로젝트에서도 재사용할 수 있으며, 새로운 기능을 추가하거나 기존 기능을 확잔하는 데 유용하다.
- 추상화: 메서드를 사용하는 곳에서는 메서드의 구현을 몰라도 된다. 프로그램의 다른 부분에서는 복잡한 내부 작업에 대해 알 필요 없이 메서드를 사용할 수 있다.
- 테스트와 디버깅 용이성: 개별 메서드는 독립적으로 테스트하고 디버그할 수 있다. 이는 코드의 문제를 신속하게 찾고 수정하는 데 도움이 된다.
반환 타입
반환 타입이 있는 메서드는 반드시 return을 사용해서 값을 반환해야 한다. 만약 return문을 누락하면 컴파일 오류가 발생한다. return 문을 만나면 그 즉시 메서드를 빠져나간다.
메서드 호출과 값 전달
자바는 항상 변수의 값을 복사해서 대입한다. 다음 코드를 보자.
package method;
public class MethodValue1 {
public static void main(String[] args) {
int num1 = 5;
System.out.println("1. changeNumber 호출 전, num1: " + num1); // num1: 5
changeNumber(num1);
System.out.println("4. changeNumber 호출 후, num1: " + num1); // num1: 5
}
public static void changeNumber(int num2) {
System.out.println("2. changeNumber 변경 전, num2: " + num2); // num2: 5
num2 = num2 * 2;
System.out.println("3. changeNumber 변경 후, num2: " + num2); // num2: 10
}
}
결과적으로 매개변수 num2의 값만 10으로 변경되고 num1의 값은 변경되지 않고 기존 값인 5로 유지된다. 자바는 항상 값을 복사해서 전달하기 때문에 num2의 값을 바꾸더라도 num1에는 영향을 주지 않는다. 위 코드를 호출자의 변수 이름과 매개변수의 이름을 같게한 다음 코드를 보자.
package method;
public class MethodValue2 {
public static void main(String[] args) {
int number = 5;
System.out.println("1. changeNumber 호출 전, number: " + number); // number: 5
changeNumber(number);
System.out.println("4. changeNumber 호출 후, number: " + number); // number: 5
}
public static void changeNumber(int number) {
System.out.println("2. changeNumber 변경 전, number: " + number); // number: 5
number = number * 2;
System.out.println("3. changeNumber 변경 후, number: " + number); // number: 10
}
}
main()의 number와 changeNumber()의 number는 서로 다른 변수이다. 메서드를 사용해서 값을 변경하려면, 메서드의 호출 결과를 반환 받아서 사용하면 된다. 다음 코드를 보자.
package method;
public class MethodValue3 {
public static void main(String[] args) {
int num1 = 5;
System.out.println("changeNumber 호출 전, num1: " + num1); // num1: 5
num1 = changeNumber(num1);
System.out.println("changeNumber 호출 후, num1: " + num1); // num1: 10
}
public static int changeNumber(int num2) {
num2 = num2 * 2;
return num2;
}
}
자바는 참조형 변수에 있는 값인 참조값을 복사하는 것이다.
메서드와 형변환
메서드를 호출할 때도 형변환이 적용된다.
명시적 형변환
메서드를 호출하는데 인자와 매개변수의 타입이 맞지 않은 경우를 보자.
package method;
public class MethodCasting1 {
public static void main(String[] args) {
double number = 1.5;
// printNumber(number); // double을 int형에 대입하므로 컴파일 오류
printNumber((int) number); // 숫자: 1
}
public static void printNumber(int n) {
System.out.println("숫자: " + n);
}
}
자동 형변환
메서드를 호출할 때 매개변수에 값을 전달하는 것도 결국 변수에 값을 대입하는 것이다. 따라서 자동 형변환이 그대로 적용된다. (int < long < double)
package method;
public class MethodCasting2 {
public static void main(String[] args) {
int number = 100;
printNumber(number); // int에서 double로 자동 형변환
}
public static void printNumber(double n) {
System.out.println("숫자: " + n);
}
}
메서드를 호출할 때는 전달하는 인수의 타입과 매개변수의 타입이 맞아야 한다. 단, 타입이 달라도 자동 형변환이 가능한 경우에는 호출할 수 있다.
메서드 오버로딩
자바는 메서드의 이름 뿐만 아니라 매개변수 정보를 함께 사용해서 메서드를 구분한다. 따라서 이름이 같고, 매개변수가 다른 메서드를 정의할 수 있다.
이름이 같고 매개변수가 다른 메서드를 여러개 정의하는 것을 메서드 오버로딩(Overloading)이라 한다. 참고로 반환 타입은 인정하지 않는다.
int add(int a, int b);
double add(int a, int b); // 오버로딩 실패
메서드 시그니처(method signature)는 자바에서 메서드를 구분할 수 있는 고유한 식별자나 서명을 뜻한다. 메서드 시그니처는 메서드의 이름과 매개변수 타입(순서 포함)으로 구성되어 있다. 즉, 매서드를 구분할 수 있는 기준이다. 자바 입장에서는 각각의 메서드를 고유하게 구분할 수 있어야한다. 그래야 어떤 메서드를 호출 할 지 결정할 수 있다.
따라서 메서드 오버로딩에서 설명한 것 처럼 메서드 이름이 같아도 메서드 시그니처가 다르면 다른 메서드로 간주한다. 반환 타입은 시그니처에 포함되지 않는다. 예를 들어, 위 두 메서드는 add(int a, int b)로 메서드 시그니처가 같다. 따라서 메서드의 구분이 불가능하므로 컴파일 오류가 발생한다.
댓글남기기