메서드 (Methods)

2023. 11. 23. 15:39
728x90

1. 메서드 개요

만약 내가 여러번 반복해서 쓰고 싶은 코드들이 있다면...?

매번 복붙하는 것보다... 코드를 한 곳에 모아놓고 그 코드만 불러들여서 쓴다면...? 

훨씬 효율적이다 ! 

>> 이럴 때 활용할 수 있는게 메서드이다. 

 

함수? 메서드?

- 함수 : 독립적으로 실행될 수 있는 코드 조각

- 메서드 : "특정 클래스"와 연결되어 그 클래스 객체에서 수행하는 기능

 

 

쉽게 말해
점점 길어지고 중복된 기능인 부분을 따로 빼내고, 이름을 붙여 메서드를 만든다.

 

 

 

 

* main 메서드

: 프로그램의 시작점(entrypoint)를 정의하는 메서드

public class Main {
	public class void main(String[] args) {
    	System.out.println("이것도 일종의 메서드");
    }
}

 

- 메서드 정의하기 

public class Main {
	public static(제어자) int(반환타입) addTwo(이름) (int a, int b(매개변수)) {
    	return a+b;(리턴값)
    }
}
  • 제어자 : 접근 제어자, 정적 제어자 (클래스에서 좀더 다룸)
  • 반환타입 : 이 메서드의 결과로 만들어지는 데이터의 자료형 / void는 반환값이 없는 메서드임 (return이 굳이 필요하지 않음)
  • 이름(식별자) : 변수의 이름처럼 이 메서드를 부를 때 사용할 이름
  • 매개변수(parameter) : 메서드에 전달할 데이터를 나타내는 변수
  • return ~ : 이 메서드가 최종적으로 무엇을 반환할지

1) 매개변수(parameter)  >> "입력값"

: 메서드로 전달될 값들을 정의하기 위해 사용. 

- 개수는 필요한 만큼 사용가능 & 매개변수가 필요 없는 메서드는 비워두어도 됨.

 

2) 반환 return >> "출력값"

: 코드를 실행해서 돌려주고 싶은 결과를 만들고 return 뒤에 작성. 

- return 자체가 메서드 내에서 여러개 나올 수 있음. 코드 실행 중 만나면 결과 반환~

 

** 반환 vs 출력  다르다!!!!!~!~!

>> 출력을 하는 System.out.println() 메서드는 반환이 아니라 출력만 한다.

// 내부의 코드가 입력을 읽는다. 문자열을 반환해주는 메서드임
String line = scanner.nextLine();
// 내부의 코드가 출력을 한다. 반환은 하지 않음.
System.out.println(line);

 

3) 메서드 호출

: 메서드 이름을 가지고 호출한다. 

public class Main { 
    public static int addTwo(int a, int b) { 
    // 3) 전달된 파라미터 값을로 메서드 실행과 리턴
    // 5) 전달된 파라미터 값으로 메서드 실행과 리턴
        return a + b;
    }

    public static int subTwo(int a, int b) { //7) 전달된 파라미터 값으로 메서드 실행과 리턴 
        return a - b;
    }

    public static void main(String[] args) { //1)main에서 시작
        // ...
        int result2 = subTwo(addTwo(4, 5), addTwo(2, 3)); 
        // 2) subTwo()메서드 안의 첫번째 인자 addTwo() 메서드 호출
        // 4) subTwo()메서드 안의 두번째 인자 addTwo() 메서드 호출
        // 6) 3, 5의 리턴값을 가지고 subTwo()메서드 호출
        // 8) subTwo()메서드의 리턴값을 result2 변수에저장
        System.out.println(result2); 
    }
}

 

2. 재귀 함수

: 자기 자신을 호출하는 메서드.

 

ex. 팩토리얼 (계승) : n부터 1까지의 자연수를 전부 곱한 수

인자를 하나 줄인 다음 다시 팩토리얼 함수 호출...

factRec(n)
= n * factRec(n-1)
= n * (n-1) * factRec(n-2)
...
= n * (n-1) * ... * 2 * 1

- 재귀함수는 성능이 아닌 가독성과 편의성.

public static int factorial(int n) {
        // 종료 조건을 먼저 언급하는 것이 좋다.
        // 종료되는 조건 : 0이나 1이면 1을 반환
        if (n == 1 || n == 0) {
            System.out.println(n);
            return 1;
        } else { // 아니면 n*f(n-1)을 반환한다.
            System.out.println(n);
            return n*factorial(n-1);
        }
}

 

ex2. 피보나치 수열

// 피보나치 수열은
// F(0) = 0
// F(1) = 1
// F(2) = 2
// F(n) = F(n-1) + F(n-2)인 수의 나열이다.
// 음이 아닌 정수n을 인자로 받아 n번째 피보나치 수를 반환하는 메서드를 구현하시오.

public static int fibo(int n) {
        if (n==0||n==1) {
            return n;
        } else {
            return fibo(n-1) + fibo(n-2);
        }
}

 

 

3. 메서드 오버로딩 

: 비슷한 역할을 하는 두 메서드일 때 인자의 자료형을 달리 메서드를 정의한다..

 

int a = 1, b = 2;
long c = 1, d = 2;

addInt(a, b); 
addInt(c, d); 
// 오류발생. c,d는 long 자료형이기 때문에 
// 더 작은 int 자료형에 들어가기 위해서는 형변환이 되어야 함.
addLong(a, b);
addLong(c, d);

public static int addInt(int a, int b) {
    return a + b;
}

public static long addLong(long a, long b) {
    return a + b;
}

 

>> 이 때 굳이 이름을 다르게 하는 것이 아니라 같은 이름을 가지고 여러 조건을 정의할 수 있다~!~! 

public static int add(int a, int b) {
    return a + b;
}

public static long add(long a, long b) {
    return a + b;
}

>> 이렇게 만들어주면 메서드 호출 단계에서 전달받는 인자의 자료형에 따라 어떤 메서드를 사용할지 정해진다. 

 

 

 

?? int + int 는 범위를 벗어날 수 있으니 반환 타입을 두가지로 하는건 어떨까...???

- 반환 자료형은 메서드를 구분하는 용도로는 활용이 불가하다. 

public static int add(int a, int b) { // 반환 타입만 다른 메서드 둘
    return a + b;
}

public static long add(int a, int b) {
    return (long) a + b;
}

int a=1, b=2;
add(a, b);
// 자료형이 int인 a,b인 인자로 구성된 메서드가 둘 다 해당되기 때문에... 불가능!!!!
// 인자의 자료형에 따라 메서드를 호출하는데... 두 메서드의 인자 자료형이 같기 때문에 컴퓨터가 선택 불가능

 

* 가장 대표적인 메서드 오버로딩 예시 > println(); 

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

 

4. 가변인자 Varargs (Variable-length arguments lists)

임의 갯수의 인자를 받을 수 있는 기능

 

상황에 따라서... 인자의 갯수를 미리 알지 못하다면 어떻게 할까...? 

 

ex. String.format();

String.format("%d개의 인자", 2);
String.format("%d개의 인자도 받지요%c", 3, '!');
String.format("인자가 %d개라고 다를게 있을까요? %s %s", 4, "아마", "괜찮을걸요");

String.format(String s, Object...obj);

 

- 메서드 내부에서는 배열처럼 활용 가능.

- 호출 시 인자를 여러개 전달 가능.

- 배열도 전달 가능

- 가변인자와 다른 인자를 사용하고 싶다면? 가변인자를 가장 나중에 넣어야 함. (어디까지가 가변인자가 가져갈 인자인지 파악하기 어렵기 때문!)

 

public static int varNumSum(int... numbers) {
    int sum = 0;
    // 마치 배열 쓰듯이 사용
    for (int i = 0; i < numbers.length; i++) {
        sum += numbers[i];
    }
    return sum;
}


System.out.println(varIntSum(1, 2, 3, 4, 5)); // 원하는 갯수만큼 인자 전달 가능

int[] numbers = {1, 2, 3, 4};
System.out.println(varNumSum(numbers)); // 배열도 전달 가능

public static void repeatStrings(String line, int... counts) { //꼭 마지막에 가변인자 선언
    for (int count : counts) {
        for (int i = 0; i < count; i++) {
            System.out.print(line);
        }
        System.out.println();
    }
}

 

** 메서드 오버로딩과 함께 사용할 시 주의할 점! 

- 배열로 가변인자 전달이 가능하기 때문에~ 메서드의 매개변수 형태가 모호할 수 있음 (컴파일 오류)

public static int varNumSum(int... numbers) {
    // ...
}
public static int varNumSum(int[] numbers) {
    // ...
} // 둘 중 어떤 메서드를 불러들여야할지 모호함..

 

+ 만약, 같은 자료형으로 인자를 설정한다면...? 이때도 모호하다

public static int varNumSum(int... numbers) {
    // ...
}
public static int varNumSum(int base, int...numbers){
    // ...
} // 모든 인자의 자료형이 int이기 때문에 이것도 어떤 메서드를 호출할지가 모호함.

// 오류
System.out.println(varNumSum(1, 2, 3, 4, 5));

// 정상
System.out.println(varNumSum(1, new int[]{2, 3, 4, 5}));
System.out.println(varNumSum(new int[]{1, 2, 3, 4, 5}));

 

 

 

728x90

'Programming > Java' 카테고리의 다른 글

객체지향 프로그래밍  (1) 2023.11.28
클래스 (Class)  (1) 2023.11.28
제어문 (Control Statements)  (1) 2023.11.22
연산자 (Operators)  (0) 2023.11.21
변수와 자료형 (Variables and Types)  (1) 2023.11.20

BELATED ARTICLES

more