06-4 / 메소드

  • 메소드의 정의

객체의 동작에 해당하는 중괄호 {} 블록을 말하며 이 {}의 이름이 메소드 이름이다. 

메소드의 이름으로 호출하게 되면 중괄호 내의 모든 코드들이 일괄적으로 실행된다. 

 

메소드 선언은 선언부와 실행 블록으로 구성되는데 아래와 같이 선언되며 {}를 제외한 나머지 부분이 선언부며 이를 메소드 시그니처라고 한다.

리턴타입 메소드이름 ([매개변수1, 매개변수2...]){
}
리턴 타입 메소드가 리턴하는 결과의 타입 표시
메소드 이름 기능을 알 수있게 그리고 식별자 규칙에 맞게 명명해야 한다.
매개 변수 선언 선택사항으로 메소드 실행시 필요한 데이터를 받기 위한 변수.
메소드 실행 블록 실행할 코드를 작성

 

 


매소드 선언) 

  • 리턴 타입

메소드를 실행한 후의 결과값인 리턴 값의 타입을 말한다. 

 

메소드는 리턴 값의 자료형에 따라 메소드 이름 앞에 그 타입을 적어두게 되는데 이때의 패턴은 크게 두가지로 나눌 수 있다.

리턴값이 없는 메소드 void 무효라는 의미로 리턴이 없는 자료형을 의미
리턴값이 있는 메소드 해당 자료형 돌려줄 리턴값의 타입에 따라 다르게 선언

 

 

  •  메소드 이름

식별자 규칙에 맞게 작성해야 한다.

- 숫자로 시작 불가

- $ (달러사인), _(언더바) 제외한 특수 문자 사용 불가

- 관례적으로 메소드이름은 소문자 사용, 단 여러단어 혼합시 뒤이어 오는 단어 첫글자는 대문자.

void run(){...}
void startEnging(){...}
int[] getScore(){...}
String getName(String name){...}

 

 

  • 매개 변수 선언

메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용된다. 필요한 경우에만 매개변수를 선언해 사용하며, 매개변수가 필요없는 경우도 있다.

double divide(int x, int y){
	double result = (double)x / (double)y;
    return double;
}
double result = divide(10, 20);
System.out.println(result);
// 0.5

 

 

  • 매개 변수의 개수를 모를 경우

변수의 개수를 입력해야 될지 모를때에는 매개변수를 배열 타입으로 선언하는 것으로 해결할 수 있다. 

int sum(int[] values){ }

매개값인 배열 항목 수는 호출할 때 결정된다.

 

매개 변수를 배열 타입으로 선언하면 메소드 호출전에 배열을 생성해야하는 불편함이 있는데 이는 매개값 위치에 값 목록을 바로 넣어 줌으로써 값을 바로 넘기는 방법도 있다.

- 원래라면

int[] arr = {1,2,3};
int result = sum1(arr);
//또는
int result = sum1(new int[]{1,2,3});

- 바로 값 목록을 넘긴다면

int sum1 (int ... values) {} // 매개값의 타입 뒤에 ...은 생략이 아닌 저 표기로 써야 적용
int result = sum1(1,2,3);

 

 


리턴(return) 문) 

  • 리턴값이 있는 메소드

리턴 타입이 있는 메소드는 반드시 리턴문을 사용해서 리턴값을 지정해야한다. (없으면 컴파일 에러 발생)

이런 메소드는 return문이 실행되면 메소드는 리턴값을 반환하고 즉시 종료 된다.

return 리턴값;

return문의 리턴값은 리턴 타입이거나 리턴 타입으로 변환 될 수 있어야 한다.

(ex. byte, short, int는 int값으로 리턴되는 메소드의 리턴값이 될 수 있다.)

 

 

  • 리턴값이 없는 메소드 : void

리턴값이 없는 메소드는 타입으로 void를 선언한다. 그러나 이 메소드에서도 return문을 사용할 수 있는데 용도는 값을 반환하는 용도가 아니라, 메소드를 종료시키기 위한 용도이다.

return;

 

 


메소드 호출) 

메소드는 클래스 내.외부의 호출에 의해 실행된다.

같은 클래스 안에서는 메소드의 이름만으로 호출이 되지만 클래스 외부에서 호출할 경우에는 우선 클래스로부터 객체를 생성한 뒤 참조 변수를 이용해 메소드를 호출해야 한다. 객체가 있어야 메소드도 존재하기 때문이다.

 

  • 객체 내부에서 호출

같은 클래스 안에서는 아래와 같이 호출이 가능하다.

메소드이름 ([매개값1, 매개값2 ... ]);

리턴값이 없어도, 리턴값이 있어도 호출이 가능하다. 다만, 리턴값이 있는 경우에는 앞에 변수를 선언하고 리턴값을 대입한다. (이때 변수는 리턴값과 동일하거나 리턴값이 자동 변환가능한 타입이어야 한다.)

타입 변수명 = 메소드([매개값1, 매개값2...]);

 

  • 객체 외부에서 호출

외부 클래스에서 메소드를 호출하려면 우선 다음과 같이 클래스로부터 객체를 생성해야 한다. 메소드는 객체에 소속된 멤버이므로 객체가 존재하지 않으면 메소드도 존재하지 않는다. 

클래스이름 참조변수명 = new 클래이스이름 ([매개값1, 매개값2, 매개...]);

위와 같이 선언되었다면 도트(.)연산자를 사용해서 메소드를 호출할 수 있다. 도트 연산자는 객체 접근 연사자로 객체가 가지고 있는 필드나 메소드에 접근할 때 사용된다.

참조변수명.메소드이름([매개값1,매개...]); // 리턴값이 없거나 리턴값을 받을 필요 없을때
타입 변수명 = 참조변수명.메소드이름([매개값1,매개...]); // 리턴값이 있고, 리턴값을 받고 싶은 때

 

 


메소드 오버로딩) 

클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것을 메소드 오버로딩이라 한다.

오버로딩은 매개값을 다양하게 받아 처리할 수 있도록 하기 위해 사용된다. 

하나의 메소드 이름으로 여러기능을 담는다 하여 붙여진 이름으로

오버로딩 조건은 매개 변수의 타입, 개수, 순서 가 전부 달라야 한다는 점에 있다. 

// 모두 오버로딩 되어 별개 기능 사용가능
int plus (int x, int y) {...}
int plus (int x, int y, int z) {...}
int plus (double x, double y) {...}
int plus (int x, double y) {...}
int plus (double x, int y) {...}

위의 메소드들은 모두 plus라는 이름을 가지고 있지만 다른 메소드들로 별개의 기능이 가능하다.

그러나 아래는 각각 동일한 메소드다. 타입과 개수, 순서 모두 동일하기 때문 변수명을 달리했다고 달라지는 것은 아니다. 

// 아래 두개 동일
int plus (int x, int y) {...}
int plus (int num1, int num2) {...}

// 아래 두개 동일
int plus (String operater, int number) {...}
int plus (String calculator, int num) {...}

JVM은 메소드를 호출할 때 먼저 매개값을 체크해 메소드를 선택한다.

그렇다면 아래와 같은 경우는 어떨까

int plus (int x, int y) {...}
double plus (double x, double y) {...}

int num1 = 10;
double num2 = 30.0;

plus(num1, num2); 

// double 타입으로 반환하는 plus가 실행되며,
// 컴파일 에러가 발생하지 않고 num1이 double로 자동변환되어 메소드를 실행한다.

들어가는 변수와 매개값의 타입이 일치하지 않는 상황에 모두 컴파일 에러가 뜨는 건 아니다. 

매개값의 타입으로 자동 변환이 가능한 변수의 경우, 자동변환 여부를 검사해 가능하면 변환하여 그에 맞는 메소드를 선택해 실행한다.

 

오버로딩된 메소드들 중 우리가 가장 친근하게 본 것을 꼽자면 System.out.println(); 일텐데 우리는 다 같은 거라고 생각했지만 실제로는 들어가는 매개값 타입에 따라 여러 System.out.println 중 하나를 호출해서 사용한 것이다.

void println() {...}
void println(boolean x) {...}
void println(char x) {...}
void println(char[] x) {...}
void println(double x) {...}
void println(float x) {...}
void println(int x) {...}
void println(long x) {...}
void println(Object x) {...}
void println(String x) {...}
...

 

 

 

 

 


Question
+ 매개변수 개수를 모를 때 배열로 넘기는데 main 메소드의 args라는 이름의 String[] 배열도 그런걸까? 
그럼 args에는 뭐가 넘어오는 걸까? 

 

 

+ Recent posts