클라이언트/ 서버/ 엔지니어 " 게임 개발자"를 향한 매일의 공부일지

클래스와 객체 11 - 메소드의 활용 본문

프로그래밍 언어/자바

클래스와 객체 11 - 메소드의 활용

huenuri 2024. 8. 18. 02:16

메소드는 이전에 클래스 전에 학습했지만 책에도 이런 내용이 있는줄 몰랐다. 책으로 보면 더 자세하게 개념을 짚을 수 있을 것 같다. 그러면 학습을 시작해보자!


 

 

 

1. 메소드 형식

메소드는 클래스의 멤버 함수로서 메소드 앞에 접근 지정자를 선언한다는 점을 제외하면 C/C++ 함수 작성법과 동일하다. 접근 지정자는 public, private, protected, 디폴트의 4가지 유형으로 메소드가 다른 클래스에서 호출될 수 있는지 지정하기 위해 사용한다.

public int getSum(int i, int j) {
	int sum;
    sum = i + j;
    return sum;
}

 

 

 

 

2. 인자 전달

자바의 메소드 호출시 인자 전달 방식은 '값에 의한 호출'이다. 호출하는 신인자의 값이 복사되어 메소드의 개매 견수에 전달된다.

 

1. 기본 타입의 값이 전달되는 경우

메소드의 매개변수가 기본 타입(byte, char, short, int, long, float, double, boolean)으로 선언된 경우, 호출자가 건네는 값이 매개변수에 복사되어 전달된다. 다음 코드는 변수 n에 저장된 값10을 increase() 메소드에 전달한다.

int n = 10;
increase(n);

 

increse(int m) 메소드가 호출되면, 매개변수 m이 생성되고 10으로 초기화된다. 그러고나서 m값을 1 증가시킨다. increase()에서 리턴하여 main() 메소드로 돌아오면 변수 n 값은 여전히 10으로 남아있다.

 

 


 

 

 

 

2. 객체가 전달되는 경우

메소드의 매개변수가 클래스 타입인 경우, 객체가 아니라 객체의 레퍼런스 값이 전달된다.

increase(pizza);

 

이 호출문에 의해 increase(Circle m)가 호출되면 매개변수 m이 생기고, pizza 변수에 저장된 값(레퍼런스)이 m에 복사되어, m은 pizza가 가리키는 객체를 함께 가리키게 된다. 그러므로 m.radius++;에 의해 radius는 11로 변경되고 increase()가 종료한 후에도 그대로 남는다.

메소드 호출 시 객체가 전달되는 경우, 객체에 대한 레퍼런스만 전달되지 객체가 통째로 복사되지 않는다는 점에 유의하자.

 


 

 

 

 

 

3. 배열이 전달되는 경우

배열이 메소드에 전달되는 경우도 객체 레퍼런스가 전달되는 경우와 동일하다. 배열이 통째로 전달되는 것이 아니며 배열에 대한 레퍼런스만 전달된다.

main()에서 생성된 배열 a가 increase()에 전달된다. increase(int[ ] array)의 매개변수 array는 정수형 배열에 대한 레퍼런스로서 배열 a를 가리키게 되어 두 레퍼런스로서 배열은 a를 가리키게 되어 두 레퍼런스는 하나의 배열을 공유하게 된다. increase() 메소드에서 array 배열의 각 원소를 1씩 증가시키고 리턴한 후 main()에서 배열 a를 출력하면 변경된 값 2 3 4 5 6이 출력된다.

 


 

 

 

인자로 배열이 전달되는 예

char[ ] 배열을 전달받아 출력하는 printCharArray() 메소드와 배열 속의 공백(' ') 문자를 ','로 대치하는 replacespace() 메소드를 작성하라.

 

 

 

이렇게 메소드를 호출해서 메인에서 부르면 출력이 된다. 메소드에서는 해당 기능을 자세히 기록하여 분리할 수 있으니 코드가 훨씬 더 간결해지고 구조화되는 것 같다.


 

 

 

 

3. 메소드 오버로딩

자바에서는 한 클래스 내에, 이름은 같지만 매개변수의 타입이나 개수가 서로 다른 여러 개의 모세도를 중복 작성할 수 있다. 이것을 메소드 오버로딩(method overloading) 혹은 메소드 중복이라고 부른다. 여러 개의 메소드가 오버로딩되려면 다음 두 조건을 모두 만족하여야 한다.

  • 메소드 이름이 동일하여야 한다.
  • 매개변수의 개수나 타입이 서로 달라야 한다.

메소드의 리턴 타입이나 접근 제정자는 메소드 오버로딩과 관계 없다.


 

 

 

메소드 오버로딩 성공 사례

다음은 5개의 getSum() 메소드가 정상적으로 오버로딩된 사례이다. 메소드 이름이 동일하고 개배변수의 개수가 서로 다르기 때문에 두 메소드는 한 클래스 내에 공존하는데 아무 문제가 없다.

class MethodOverloading {	// getSum() 메소드의 정상적인 오버로딩 사례
    public int getSum(int i, int j) {
    	return i + j;
    }
    public int getSum(int i, int j, int k) {
    	return i + j + k;
    }
}

 

 

 

메소드 오버로딩 실패 사례

메소드 오버로딩은 자바 컴파일러에 의해 판단되며, 컴파일러가 이름이 같은 메소드들을 구분할 수 있으면 메소드 오버로딩이 성공한다. 

class MethodOverloadingFail {	// 메소드 오버로딩이 실패한 사례
    public int getSum(int i, int j) {
    	return i + j;
    }
    public double getSum(int i, int j) {
    	return (double)(i + j);
    }
}

 

 

 

 

오버로딩된 메소드 호출

MethodSample 클래스에는 3개의 getSum() 메소드가 작성되어 있고 main() 메소드는 getSum()을 호출하는 여러 문장이 있다. 자바 컴파일러는 각 호출문에 대해, 매개변수의 타입과 개수에 일치하는 getSum() 메소드를 찾아낸다.

 


 

 

 

 

핵심 체크 문제 풀어보기

1. double 타입의 일차원 배열얼 매개변수로 전달받아 배열의 합을 리턴하는 getSum() 메소드를 작성하라.

 

 

문제에서는 메소드만 만드는 거였지만 난 뭔가 출력을 해보고 싶었다. 이렇게 하면 문제가 더 잘 보이기 때문이다. 합계를 구하니 소숫점이 너무 많아서 첫째 자리만 출력하도록 수정해보았다.

 

나머지 문제는 이론 문제라서 책에 풀어도 될 것 같다. 그래도 3번 문제는 한번 이야기해보려고 한다.


 

 

 

2. 메소드가 배열을 전달받는 경우 메소드 내에서 배열 원소의 값을 변경하면 원본 배열의 값이 변경되는가?

 

메소드 호출시 배열의 레퍼런스만 복사되므로 메소드에서 원본 배열의 값을 변경할 수 있다. 이것은 자바에서 배열이 참조 타입(reference type)으로 동작하기 때문이다. 참조 타입은 실제 데이터를 저장하는 메모리 주소를 참조하므로, 배열을 메서드에 전달하면 해당 배열의 메모리 주소가 전달된다. 따라서 메서드 내에서 배열의 원소를 수정하면, 그 수정이 원본 배열에도 반영된다.

그냥 개념적으로 설명하면 무슨 말인지 잘 모를 수도 있으니 예제를 만들어보며 이 부분을 좀더 설명해보려고 한다.

 

 

 

이렇게 원본의 값이 수정된다는 걸 알게 되었다. 

 


 

 

 

학습을 마치고

오늘 새벽 2시 넘어서까지 공부하고 있다. 오늘은 여기까지 공부하려고 한다. 비록 약속을 지키지 못한 부분도 있지만 나름 잘한 부분도 많이 있었다. 매일 한 가지씩 중요한 일들에 도전해볼 것이다.

오늘도 공부하느라 수고가 많았다.