메서드 (Method)?
메서드(method)는 특정 작업을 실행하는 일련의 문장들을 하나의 세트로 묶어놓은 것이다.
함수를 생각하면 비슷한데 예를 들어 제곱근을 구하는 메서드 Math.sqrt( )에 16을 넣으면 4를 반환한다. println( ), random( )등도 메서드이다. **다만 함수와 다른 점은 메서드는 입/출력 값이 없을 수 있다는 점
사용 이유
높은 재 사용성
중복된 코드의 제거
프로그램의 구조화
메서드의 구조
메서드의 구조는 선언부(header or method signature )와 구현부(body or method body)로 나눌 수 있다.
반환타입 메서드이름 (타입 변수명, 타입 변수명, ....) ----선언부
{
메서드 호출 시 수행될 코드 ----{ } 내부는 구현부
}
int multiplier (int a, int b) ----선언부
{
int result = a * b; ----{ } 내부는 구현부
return result;
}
반환 타입이 있을 때 반드시 메서드 안에 return 문이 포함되어야 한다.
이때 return으로 반환되는 값은 위에서 선언부에서 정의한 반환 타입과 일치하거나 적어도 자동 형 변환이 가능한 상태여야 한다. 즉 위의 코드에서 int로 반환 타입을 지정했으니 return으로 받는 값도 int형 이어야 한다.
반환 값이 없는 경우 반환 타입으로 void를 써야 한다.
메서드의 호출
메서드를 정의해도 호출을 하지 않는다면 아무 일도 일어나지 않는다. 해당 메서드를 이용하기 위해선 호출을 해야 한다.
메서드 이름 ();
메서드이름 (값1, 값2, ...);
// 인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야한다.
==============================
doNothing(); // doNothing()를 호출한다.
multiplier (5, 6); // int multiplier (int a, int b)를 호출하고, 결과를 result에 반환
5와 6이 multiplier 메서드의 매개변수 int a, int b에 대입이 된다. 그리고 {} 안의
연산을 실행후 값을 리턴한다. 여기서 결과는 30을 리턴할 것이다.
int multiplier (int a, int b)
{
int result = a * b;
return result;
}
클래스 메서드(Static)와 인스턴스 메서드
변수와 마찬가지로 메서드 앞에 static이 붙어있으면 클래스 메서드이고 붙어있지 않다면 인스턴스 메서드이다.
클래스 메서드도 클래스 변수처럼 객체를 따로 생성하지 않고도 '클래스이름.메서드이름(매개변수)' 와 같은 형식으로 호출이 가능하다.
반면에 인스턴스 메서드는 반드시 객체를 사전에 생성해야 호출이 가능하다.
클래스 메서드 == 인스턴스와 관계가 없는(인스턴스 변수나 메서드를 사용하지 않는) 메서드
인스턴스 메서드 == 메서드의 기능을 진행하는데 인스턴스 변수를 필요로 하는 메서드
특징들을 정리하자면:
1. 클래스를 생성할 때, 멤버 변수 (클래스 영역 내에 선언된 변수: 클래스 변수 / 인스턴스 변수) 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
만들어진 인스턴스는 독립적인 저장공간을 갖는다. 따라서 각자 다른 값을 유지하게 되는데 만약 모든 인스턴스에서 동일한 값이 유지되어야 하는 변수가 필요하다면 앞에 static을 붙여 클래스 변수로 정의해야 한다.
2. 클래스 변수(static 변수)는 인스턴스가 없어도 사용 가능하다.
static이 붙은 변수 (클래스 변수)는 클래스가 메모리에 로딩되는 시점에 자동적으로 생성된다.
3. 클래스 메서드(static 메서드)는 인스턴스 변수를 사용할 수 없다.
클래스 메서드는 인스턴스를 생성하지 않고 바로 호출을 할 수 있다. 그렇기 때문에 호출을 했을 때 인스턴트 변수가 존재하지 않는 상황이 있을 수 있어 클래스 메서드에서의 인스턴스 변수의 사용은 금지된다.
하지만 인스턴스 변수나, 인스턴스 메서드에서는 static이 붙은 멤버를 사용하는 게 항상 가능한데, 인스턴스 변수가 있다는 것은 이미 static 변수가 메모리상에 존재하는 것을 의미하기 때문이다.
4. 메서드 안에서 인스턴스 변수를 사용하지 않는다면, static 사용을 고려한다.
메서드의 작업을 위해서 인스턴스 변수를 필요로 할 때는 static을 붙일 수 없다. 그 반대로, 작업을 위해 인스턴스 변수가 필요하지 않다면 static을 붙이는 것이 호출시간이 짧아 성능의 향상을 볼 수 있다.
(유의미한 차이인지에 대한 정보는 얻지 못했다)
static을 붙이지 않은 인스턴스 메서드는 실행되었을 때 호출해야 하는 메서드를 찾는 프로세스가 추가적으로 필요하기 때문에 시간이 더 소요된다.
키 포인트
클래스의 멤버 변수 (클래스 / 인스턴스 변수)중 모든 인스턴스에 같은 값을 저장해야 한다? -> static 붙인다.
작성한 메서드가 인스턴스 변수 & 메서드를 사용하지 않는다? -> static을 고려해봐라
메서드 오버 로딩
메서드 오버 로딩은 하나의 클래스 안에 같은 이름의 여러 메서드를 정의하는 것을 말한다.
처음에는 굳이 왜??? 하는 생각이 들었으나 "하나의 메서드로 여러 경우의 수를 해결할 수 있으며 이름만 기억하면 되니 기억하기도 쉽고 이름도 짧게 할 수 있어 오류의 가능성을 낮출 수 있다"라는 이유를 알고 나니 잘 쓰면 편하겠다 싶었다.
대표적인 케이스로 println( )이 있는데 지금까지 println을 쓰면서 안에 타입을 지정하는 등의 특정한 행동을 하지 않고도 괄호 안에 출력하고 싶은 내용을 입력하면 되는 걸로 알고 있었다. 그리고 이게 메서드 인지도 몰랐다.
하지만 실제로는 println 메서드를 호출할 때 괄호 안의 매개변수로 지정하는 값의 타입에 따라 호출되는 println 메서드가 다르다! PrintStream이라는 클래스 안에 10개의 오버 로딩된 println 메서드가 정의되어 있는데 이에 따라 매개변수로 어떤 값이 들어오던 오버 로딩된 메서드들 중에서 맞는 타입인 메서드를 선택해 실행한다.
void println() / boolean x / char x / char [] x / double x / float x / int x / long x / Object x / String x
메서드 오버 로딩은 단순히 이름만 같게 해서 되는 것이 아닌 특정 조건을 만족해야 오버 로딩으로 간주된다.
1. 메서드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
** 반환 타입은 오버 로딩을 구현하는 데 있어 아무런 영향을 주지 않는다.
아래의 예시 표를 보면 이해가 좀 더 잘될 것이다.
메서드 | 오버로딩 | 이유 |
int po(int x, int y) {return x + y;} int po (int i, int j) {return i + j;} |
X | 매개변수의 이름만 다를 뿐, 타입과 개수가 같다. (두 메서드는 정확히 같다) |
int po(int x, int y) {return x + y;} long po(int i, int j) {return (long)(i+j);} |
X | 리턴 타입이 다르지만 매개변수의 타입과 개수가 같다. po(10,10)을 호출하면 어느 메서드가 호출됬는지 알 수 없다. |
long p(int x, long y) {return x + y;} long p(long x, int y) {return x + y;} |
O | 호출 시 매개변수의 값으로 호출할 메서드를 구분 가능하다. |
즉 매개변수를 통해 특정 메서드를 선택할 수 있어야 한다 |
'programming > JAVA' 카테고리의 다른 글
Java - 상속(Inheritance) (0) | 2022.05.12 |
---|---|
Java - 생성자 (0) | 2022.05.11 |
Java - 필드와 변수 (0) | 2022.05.10 |
Java - 클래스와 객체 (0) | 2022.05.10 |
입력받은 자연수의 소수 판별 (0) | 2022.05.08 |