6) 객체지향 프로그래밍2 - 메서드

dev-mage·2022년 10월 1일
0

Hello Java World!

목록 보기
12/32
post-thumbnail

Java의 메서드 구성요소와 메서드 오버로딩

메서드(method)

메서드는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다. 기본적으로 수학의 함수와 유사하며, 어떤 값을 입력하면 그 값으로 작업을 수행해서 결과를 반환한다. 수학의 함수와 다른 점은 메서드는 입력값이나 결과값이 없을 수도 있다는 것이다.

메서드는 크게 선언부와 구현부로 이루어져 있으며, 메서드를 정의한다는 것은 선언부와 구현부를 작성하는 것을 뜻한다.

// 메서드 선언
반환타입 메서드이름 (매개변수타입 매개변수이름, 매개변수타입 매개변수이름, ...) // 선언부
{ // 구현부
	// 메서드 호출 시 수행될 코드
}

메서드의 구성 요소

  • 선언부(header)
    • 메서드의 이름, 매개변수, 반환타입으로 구성
    • 메서드가 작업을 수행하기 위해 어떤 값들을 필요로 하고 작업의 결과로 어떤 타입의 값을 반환하는지에 대한 정보 제공

메서드 구성 요소

  1. 매개변수(parameter)
    • 메서드가 작업을 수행하는데 필요한 값들을 제공받기 위한 변수
    • 값을 입력받을 필요가 없다면 괄호 안에 아무 것도 적지 않음
  2. 반환 타입(return type)
    • 메서드의 작업수행 결과인 반환값(return value)의 타입을 명시
    • 반환값이 없는 경우 반환 타입은 void
  • 구현부(body)
    • 메서드 선언부 다음에 오는 중괄호
    • 메서드를 호출했을 때 수행될 문장들을 기입
    • retur문
      • 작업을 수행한 결과인 반환값을 호출한 메서드로 전달
      • 현재 실행 중인 메서드를 종료하고 호출한 메서드로 되돌아감
      • 값의 타입은 반환 타입과 일치하거나 자동 형변환이 가능한 것이어야 함
      • 메서드의 반환 타입이 void가 아닌 경우 return문을 반드시 포함해야 함
      • 반환값의 유무에 관계 없이 모든 메서드에는 적어도 하나의 return문이 있어야 하지만 반환값이 void인 경우 컴파일러가 메서드의 마지막에 ‘return;’을 자동적으로 추가함
      • 여러 개의 변수를 선언할 수 있는 매개변수와 달리 return문은 단 하나의 값만 반환할 수 있음
      • if문 조건식의 결과에 따라 return문이 실행되지 않을 수도 있기 때문에 추가적인 조치를 해주어야 함
    • 지역 변수(local variable)
      • 메서드 내에 선언된 변수
      • 매개변수도 메서드 내에 선언된 것으로 간주되므로 지역 변수임

메서드의 호출

메서드를 호출해야한 구현부의 문장들이 수행될 수 있는데 자바에서 main 메서드는 프로그램 실행 시 운영체제에 의해 자동적으로 호출된다.

// 메서드 호출
메서드이름(인수1, 인수2, ...);
  • 인수(argument)
    • 메서드를 호출할 때 괄호 안에 지정해둔 값들을 인수 또는 인자라고 함
    • 인수의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야 함
    • 인수는 메서드가 호출되면서 매개변수에 대입되므로, 매개변수의 타입과 일치하거나 자동 형변환이 가능해야 함
  • 메서드가 호출되면 지금까지 실행 중이던 메서드는 실행을 잠시 멈추고 호출된 메서드의 문장들이 실행됨
  • 호출된 메서드의 작업이 모두 끝나면 다시 호출한 메서드로 돌아와 이후의 문장들을 실행

호출 스택(call stack)

호출 스택은 메서드의 작업에 필요한 메모리 공간이다. 메서드가 호출되는 순서대로 호출 스택에 메서드를 위한 메모리가 할당되고, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수들과 연산의 중간 결과 등을 저장하는데 사용된다. 그리고 메서드가 작업을 마치면 할당되었던 메모리 공간은 반환되어 비워진다.

다음은 호출 스택을 그림으로 나타낸 것이다.

public class CallStack {
		public static void main(String[] args) {
				System.out.println("Hello");
		}
}

호출 스택

  1. JVM에 의해서 main 메서드가 호출됨으로써 프로그램이 시작됨. 이때 호출 스택에는 main 메서드를 위한 메모리 공간이 할당되고 main 메서드의 코드가 수행되기 시작.
  2. main 메서드에서 println 메서드를 호출한 상태. 아직 main 메서드가 끝난 것은 아니므로 호출 스택에 대기 상태로 남아있고 println 메서드의 수행이 시작된다. println 메서드에 의해 ‘Hello’가 출력됨.
  3. println 메서드의 수행이 완료되어 호출스택에서 사라지고 자신의 호출한 main 메서드로 돌아감. 대기 중이던 main 메서드는 println 메서드 다음부터 수행을 재개
  4. main 메서드에도 더이상 수행할 코드가 없으므로 메서드가 종료됨. 호출스택은 완전히 비워지고 프로그램도종료.

메서드 간의 호출과 참조

메서드 앞에 static이 붙으면 클래스 메서드이고 없으면 인스턴스 메서드가 된다. 클래스 메서드는 객체를 생성하지 않고도 클래스이름.메서드이름(매개변수)와 같은 식으로 호출이 가능하다. 인스턴스 메서드는 반드시 객체를 생성해야만 호출할 수 있지만 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출할 수 있다. 단, 클래스 멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다. 인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만, 클래스 멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수도 있기 때문이다.

메서드 오버로딩(method overloading)

메서드는 메서드 시그니처를 갖는다. 메서드 시그니처란, 메서드 선언부에서 메서드 이름과 매개변수의 리스트를 의미한다. 메서드도 변수와 마찬가지로 같은 클래스 내에서 서로 구별될 수 있어야 하기 때문에 각기 다른 이름을 가져야 하는데 이름이 같아도 매개변수의 개수 또는 타입이 다르면 다른 메서드 시그니처로 인식된다. 이처럼 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 ‘메서드 오버로딩'이라고 한다. 참고로 반환 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.

// 매개변수의 이름만 다를 뿐 매개변수의 타입이 같으므로 오버로딩 X
int add(int a, int b) { return a + b; }
int add(int x, int y) { return x + y; }

// 리턴 타입만 다른 경우 매개변수의 타입과 개수가 일치하기 때문에 어떤 메서드가 호출된 것인지 알 수 없음
// 오버로딩 X
int add(int a, int b) { return a + b; }
long add(int a, int b) { return (long) a + b; }

// 매개변수의 순서가 서로 다른 경우 호출 시 매개변수의 값에 의해 호출될 메서드가 구분될 수 있음
// 오버로딩 O
long add(int a, long b) { return a + b; }
long add(long a, int b) { return a + b; }

References

  • 자바의 정석 CHAPTER 6

0개의 댓글