메서드란? : 현실의 객체가 하는 동작을 프로그래밍화한 것입니다.
메서드를 작성하는 이유
메서드 작성 방법
<제한자> <리턴 타입> <메서드명> ([<파라미터>타입 변수명],...) // 선언부
{
// 구현부
}
리턴 타입 : 메서드를 호출한 곳으로 반환되는 값의 타입으로 아무것도 리턴하지 않을 경우 void를 사용합니다.
파라미터 : 메서드 호출 시점에 넘겨줘야하는 변수들로 넘겨줄 정보가 없을 경우 생략 가능합니다.
cf) 메서드 선언 시 동일 타입의 인자가 몇 개가 들어올 지 예상할 수 없거나 가변적일 경우, ... 기호를 활용해서 여러 개의 파라미터를 넘겨줄 수 있습니다.
EX)
class VariableTest{
public void addAll(int ...params) {
int sum = 0;
for(int i : params) // params는 배열과 같은 형태로 받아옴
{ sum += i; }
System.out.println(sum);
}
}
public class Main {
public static void main(String[] args) {
VariableTest vt = new VariableTest();
vt.addAll(1,2,3); // 6
vt.addAll(1,2,3,4,5); // 15
vt.addAll(1,2); // 3
}
}
메서드 활용 예시
class Person {
String name;
int age = 0;
void toString(){
System.out.println(name+" : "+age);
}
}
// 메서드를 사용하지 않을 경우
Person p1 = new Person();
System.out.println(p1.name+" : "+p1.age);
Person p2 = new Person();
System.out.println(p2.name+" : "+p2.age);
// 메서드를 사용할 경우
Person p1 = new Person();
Person p2 = new Person();
p1.toString();
p2.toString();
메서드를 사용하지 않으면 객체의 데이터에 직접 접근 해야하고, 멤버 변수가 바뀌거나 한다면 따로따로 수정해줘야하는 불편함이 있습니다. 하지만 메서드를 사용하면 main함수의 코드가 간결해지고, 모듈화가 되어있기 때문에 객체에서만 변경해주면 모든 코드에 적용할 수 있습니다.
메서드 호출 : 메서드의 선언부에 맞춰서 이름과 파라미터 갯수를 동일하게 호출합니다.
메서드 접근 : 멤버 변수와 마찬가지로 static 또는 non static 상태를 구분해서 호출합니다.
| 비고 | static member | instance member |
|---|---|---|
| 소속 | 클래스 | 객체 |
| 같은 클래스 | 바로 호출 | 바로 호출 |
| 다른 클래스 | 클래스이름.멤버이름 | (객체 생성 후)객체이름.멤버이름 |
메서드 호출 스택 : 각각 메서드 호출 시 마다 메서드 동작을 위한 메모리를 쌓음
Overloading : 동일한 기능을 수행하는 메서드의 추가 작성할 때 사용합니다.
동일한 기능을 여러 형태로 정의할 때 사용됩니다.
- 장점 : 기억해야할 메서드가 감소하고 중복 코드에 대해 효율적 관리가 가능합니다.
활용 방법
EX)
// 주어진 파라미터를 더하는 메서드 구현
// 파라미터 이름만 다를 경우
int add(int a, int b) {return a + b;}
int add(int x, int y) {return x + y;} // 오류
// 리턴 타입이 다른 경우
int add(int a, int b) {return a + b;}
long add(int a, int b) {return a + b;} // 오류
// 파라미터의 타입이 다른 경우
int add(int a, int b) {return a + b;}
long add(long a, long b) {return a + b;} // 메서드 오버로딩
// 파라미터의 수가 다른 경우
int add(int a, int b) {return a + b;}
int add(int a, int b, int c) {return a + b + c;} // 메서드 오버로딩
<제한자> <클래스명>([인자]) {
// 맴버 변수 초기화 작업
}public DefaultConstructor() { }public ParameterConstructor() {
<멤버 변수> = <값>
}public class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
this는 객체에 대한 참조이기 때문에 static 영역에서는 사용이 불가능합니다.
public class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
Person(String name) { // 생성자 오버로딩
this(name, 0);
}
Person() { // 생성자 오버로딩
this("루키", 25);
}
}public class InitializerTest {
int iv;
static int cv;
///--1--//////////////////////////////////////
static {
System.out.println("static Initializer");
cv = 100;
}
///--4--////////////Initializer///////////////
{
System.out.println("instance initializer");
iv = 100;
}
///--3--//////////////////////////////////////
public InitializerTest() {
System.out.printf("생성자 - iv : %d, cv : %d\n", iv, cv);
this.iv = 300;
}
///--2--//////////////////////////////////////
public static void main(String args[]) {
System.out.println();
InitializerTest it = new InitializerTest(); // --> 3 --> 4 실행
System.out.printf("1 - iv : %d, cv : %d\n", it.iv, cv);
InitializerTest it2 = new InitializerTest(); // --> 3 --> 4 실행
System.out.printf("2 - iv : %d, cv : %d\n", it2.iv, cv);
}
//////////////////////////////////////////////
}
// 실행 결과 (1 -> 2 -> 3 -> 4)
//
// static Initializer
//
// instance initializer
// 셍성자 - iv : 100, cv : 100
// 1 - iv : 300, cv : 100
// instance initializer
// 셍성자 - iv : 100, cv : 100
// 2 - iv : 300, cv : 100