저번 시간엔 클래스에 대해 작성해봤는데
이번엔 클래스 안에 있는 메소드에 대해 더 자세히 알아보려고합니다!
클래스에는 객체 변수와 함께 메소드가 있습니다. 메소드(method)는 클래스 내에 구현된 함수를 말합니다.
메소드를 사용하는 이유는 무엇일까요?
첫 번째로 재사용성이 높습니다 - 한번 만들어 놓은 메소드는 얼마든지 호출할수있습니다.두 번째로는 중복된 코드가 제거됩니다 - 프로그래밍을 하다보면 반복되는 코드를 작성하는 일이 많이 생기는데이때 메소드를 활용하면 더 간결하게 코드를 작성할수있습니다.
1.변수
메소드를 알아보기 전에 변수에 대해 잠깐 살펴보겠습니다
처음에 자바를 배울때 변수는 단순히 데이터타입을 입력하고 변수명을 입력하는식으로 간단하게만 배웠지만
사실 변수에는 세 종류가 있습니다.
클래스변수, 인스턴스변수, 지역변수 입니다
class Variables {
int iv; // 인스턴스변수
static int cv; // 클래스변수(static변수, 공유변수)
void method() {
int lv = 0; // 지역변수
}
}
인스턴스 변수 의 값을 가져오려면 먼저 인스턴스를 생성해야합니다. 인스턴스는 독립적인 저장공간을 가지기때문에 서로 다른 값을 가질 수 있습니다.
클래스 변수는 인스턴스변수 앞에 static을 붙이면 되는데 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하면 클래스 변수로 선언해야합니다. 클래스가 로딩될 때 생성되어(그러므로 메모리에 딱 한번만 올라갑니다.) 종료 될 때 까지 유지되는 클래스 변수는 public 을 붙이면 같은 프로그램 내에서 어디서든 접근할 수 있는 전역 변수가 됩니다. 또한 인스턴스 변수의 접근법과 다르게 인스턴스를 생성하지 않고 클래스이름.클래스변수명 을 통해서 접근할 수 있습니다.
static에 관한 부분은 더 찾아보시면 좋을거같습니다 여기서는 간단하게만 작성했습니다!
지역변수는 메소드 내에서만 사용가능하고 메소드가 종료되면 소멸되서 사용할수 없습니다.
대표적으로 for문이나 while문 안에서 선언한 변수들은 모두 지역변수라고 생각하면 됩니다.
그래서 for문 밖에서 쓰면 에러가 나게됩니다!
2.메소드
다시 메소드에 대해 살펴보겠습니다.
메소드의 구조는 이런식으로 생겼습니다.
리턴자료형 메소드명(입력자료형1 매개변수1, 입력자료형2 매개변수2, ...) {
...
return 리턴값; // 리턴자료형이 void 인 경우에는 return 문이 필요없다.
}
메소드에는 입력값과 리턴값이 있는데
이 값에 따라서 크게 4가지로 볼수있습니다
간단하게 코드를 살펴보겠습니다
- 입력과 출력이 모두 있는 메서드
- 입력과 출력이 모두 없는 메서드
- 입력은 없고 출력은 있는 메서드
- 입력은 있고 출력은 없는 메서드
1번부터 살펴보자면
이런식으로 작성할수있다
메소드를 생성할때도 변수를 선언하는것처럼 데이터타입을 정하고 이름을 정하면된다
입력값 : int 자료형 a, int 자료형 b
리턴값 : int 자료형
int sum(int a, int b) {
return a+b;
}
2번을 살펴보면
이런식이다 위에서 본 메소드와는 다르다 입력값이 안들어가있고 리턴값만 있다
String say() {
return "Hi";
}
3번은 입력값은 있지만 리턴값이 존재하지 않는다
리턴값이 존재하지 않으면 자료형에 void라고 적으면된다.
void sum(int a, int b) {
System.out.println(a+"과 "+b+"의 합은 "+(a+b)+"입니다.");
}
마지막으로 입력과 리턴 둘다 존재하지 않는 메소드이다.
void say() {
System.out.println("Hi");
}
보통 입력이 존재하지않는 메소드는 출력문이 들어가있다
100%는 아니지만 쉽게 생각하기 위해 적은것이다.
그럼 메소드는 어떻게 쓰는걸까요?
Sample 이라는 클래스 안에 위에서 살펴본 4가지의 메소드가 존재한다고 가정했을때
sample이라는 객체(object)를 생성한다음
변수 = 객체.메소드이름(입력값)을 적으면 된다
다음처럼 sample.sum(4,3)를 입력하면
sum 이라는 메소드를 호출해서 4+3을 return 해줄것이다.
Sample sample = new Sample();
int result = sample.sum(4, 3);
이번엔 입력값이 없고 리턴값만 있는경우다
객체를 생성하고 메소드를 호출하는것까진 동일하지만 소괄호뒤에 아무런 값이 없는걸 볼수있다
메소드를 작성할때부터 입력값이 없기때문에 호출할때도 아무런 값을 넣지않는것이다.
public class Sample {
String say() {
return "Hi";
}
public static void main(String[] args) {
Sample sample = new Sample();
String a = sample.say();
System.out.println(a); // "Hi" 출력
}
}
public class Sample {
void sum(int a, int b) {
System.out.println(a+"과 "+b+"의 합은 "+(a+b)+"입니다.");
}
public static void main(String[] args) {
Sample sample = new Sample();
sample.sum(3, 4);
}
}
위의 코드는 입력값은 있지만 리턴값이 없는 경우이다
sum 메소드에는 a랑b를 더하는 출력문이 들어있다
그래서 변수에 담아주지 않아도 출력이 된다.
마지막으로 입력과 리턴 둘다 없는 메소드이다.
public class Sample {
void say() {
System.out.println("Hi");
}
public static void main(String[] args) {
Sample sample = new Sample();
sample.say();
}
}
변수에 담지도않고 값을 입력하지도 않는다
호출하면 Hi가 출력된다
메소드 호출은 = 객체.메서드명() 이라고 생각하면된다 리턴값의 유무를 꼭 생각해야한다
메모리 영역
지난 시간에 자바의 메모리 구조에 대해 간단하게 살펴봤는데
복습할겸 또 정리 해 보겠습니다.
메소드 영역 (method area)
클래스가 사용되면 JVM은 해당 클래스의 클래스파일을 읽어서 클래스에 대한 정보를 이곳에 저장합니다.
이때 그 클래스의 클래스변수도 이 영역에 함께 저장됩니다.
힙(heap)
인스턴스가 생성되는 공간, 인스턴스변수들이 생성되는 공간입니다.
호출 스택(call stack)
메소드의 작업에 필요한 메모리 공간을 제공합니다.
메소드 호출시 호출 스택에 호출된 메소드를 위한 메모리가 할당되며, 메소드가 작업을 수행하는 동안 지역변수(매개변수 포함) 들과 연산의 중간결과등을 저장하는데 사용됩니다.
메소드 작업이 끝나면 할당되었던 메모리공간은 반환되어 비워집니다.
특징
- 메소드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당
- 메소드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거
- 호출스택의 제일 위에 있는 메서드가 현재 실행중인 메소드
- 아래에 있는 메소드가 바로 위의 메서드를 호출한 메소드
이러한 코드를 실행해보겠습니다.
class CallStackTest {
public staic void main(String[] args) {
firstMethod();
}
static void firstMethod() {
secondMethod();
}
static void secondMethod() {
System.out.println("secondMethod()");
}
}
(1)~(2) 위의 예제를 실행시키면, JVM에 의해서 main메소드가 호출됨으로써 프로그램이 시작되고 이 때 호출스택에는 main메소드를 위한 메모리공간이 할당되고 main메소드의 코드가 수행되기 시작합니다.
3) main메소드에서 firstMethod()를 호출한 상태이다. 아직 main에서드가 끝난 것은 아니므로 main메소드 는 호출스택에 대기상태로 남아있고 firstMethod()의 수행이 시작됩니다
4) firstMethod() 에서 다시 secondMethod() 를 호출하고 firstMethod() 는 secondMethodl()가 수행을 마칠 때까지 대기상태에 있게 되는데 secondMethod()가 수행을 마쳐야 firstMethod() 의 나머지 문장들을 수행 할 수 있기 때문입니다.
5) secondMethod() 에서 printin()을 호출하면 println메서드에 의해 'secondMethod()'가 화면에 출력된다.
6) println메서드의 수행이 완료되어 호출스택에서 사라지고 자신을 호출한 second Method()로 되돌아갑니다. 대기 중이던 secondMethod() 는 println()을 호출한 이후부터 수행을 재개하게됩니다.
7) secondMethod() 에 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 firstMethod()로 돌아갑니다.
8) firstMethod()에도 더 이상 수행할 코드가 없으므로 종료되고, 자신을 호출한 main메소드로 돌아갑니다.
9) main메소드에도 더 이상 수행할 코드가 없으므로 종료되어, 호출스택은 완전히 비워지게 되고 프로그램 은 종료!
메모리 영역은 잘 이해가 안되서 책을 참고했는데 중요한 부분이라 반드시 개념을 이해해야 할것 같네요
다음에도 자바 객체지향에 대해 더 살펴보겠습니다
'Java > 객체지향' 카테고리의 다른 글
자바 클래스, 객체 (0) | 2024.02.01 |
---|