공부/Java

[Java-06] 객체지향프로그래밍 - 변수, 메서드

줭♪(´▽`) 2021. 2. 17. 11:25

1. 변수(variable)

- 변수의 선언된 위치에 따라 변수의 종류가 결정된다.

 

변수의 종류 선언위치 생성시기
인스턴스변수
(instance variable)
클래스 영역 인스턴스가 생성되었을 때
클래스변수
(class variable)
클래스가 메모리에 올라갈 때
지역변수
(local variable)
클래스 영역 이외의 영역
(메서드, 생성자, 초기화 블럭 내부)
변수 선언문이 수행되었을 때

 

class Variables {
    int tv;			// 인스턴스변수
    static int cv;		// 클래스변수 (static변수, 공유변수)
    
    void method() {
    	int lv = 0;		// 지역변수
    }
}

 

1) 인스턴스변수(instatnce variable)

- 클래스 영역에 선언, 클래스의 인스턴스를 생성할 때 만들어짐

- 인스턴스를 먼저 생성해야 함

- 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있음

- 인스턴스마다 고유한 상태를 유지해야하는 속성 -> 인스턴스변수로 선언

 

2) 클래스변수(class variable)

- static을 앞에 붙인 변수

- 모든 인스턴스가 공통된 저장공간(변수)을 공유함

- 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성 -> 클래스변수로 선언

- 인스턴스변수와 달리 인스턴스를 생성하지 않고도 '클래스이름.클래스변수'로 언제든지 사용 가능

- 클래스가 메모리에 로딩(loading)되어 프로그램이 종료될 때 까지 유지됨

- public을 앞에 붙이면 전역변수(gloal variable, 같은 프로그램 내에서 어디서나 접근 가능한 변수)의 성격을 가짐

 

3) 지역변수(local variable)

- 메서드 내에 선언, 메서드 내에서만 사용 가능

- 메서드가 종료되면 소멸됨

- for문 또는 while문의 블럭 내에서 선언된 지역변수는 해당 블럭에서만 사용 가능

 

 

※ 클래스변수와 인스턴스변수 차이

인스턴스변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스변수는 모든 인스턴스가 하나의 저장공간을 공유하므로 항상 공통된 값을 가짐

 

2. 메서드(method)

1) 메서드란?

- 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것 (수학의 함수와 유사)

- 어떤 값을 입력하면 이 값으로 작업을 수행해서 결과를 반환함 (하지만 입력값과 출력값이 없을 수도 있음)

 

2) 메서드를 사용하는 이유

① 높은 재사용성(reusability)

- 한번 만들어 놓은 메서드는 몇 번이고 호출할 수 있으며, 다른 프로그램에서도 사용 가능

 

② 중복된 코드의 제거

- 반복되는 문장들을 묶어서 하나의 메서드로 작성해 놓으면, 반복되는 문장들 대신 메서드를 호출하는 한 문장으로 대체할 수 있음

- 전체 소스 코드의 길이도 짧아짐

- 변경사항이 발생했을 때 수정해야할 코드의 양이 줄어듦

- 오류가 발생할 가능성이 낮아짐

 

③ 프로그램의 구조화

- 큰 규모의 프로그램에서는 문장들을 작업단위로 나눠서 여러 개의 메서드에 담아 프로그램의 구조를 단순화시키는 것이 필수적임

- 프로그램의 구조를 단순화해야 프로그램에 문제가 발생해도 해당 부분을 쉽게 찾아서 해결할 수 있음

 

3. 메서드의 선언과 구현

- 메서드는 크게 '선언부(header, 머리)'와 '구현부(body, 몸통)'로 이루어짐

1) 메서드 선언부(method declaration, method header)

- 메서드 이름, 매개변수 선언, 반환타입으로 이루어짐

- 메서드가 작업을 수행하기 위해 필요로 하는 값과 작업의 결과로 반환할 값의 타입에 대한 정보 제공

 

메서드 선언부의 구성, 두 개의 int타입 값을 받아 int타입 값을 반환함

 

- 반환타입(return type) : 메서드의 작업수행 결과(출력)인 반환값(return value)의 타입을 적음

(반환값이 없는 경우 void)

- 메서드 이름(method name) : 변수의 명명규칙처럼 작성, 의미있는 이름으로 짓기

- 매개변수 선언(parameter declaration) : 메서드가 작업을 수행하는데 필요한 값들(입력)을 제공받기 위한 것으로 필요한 값의 개수만큼 변수를 선언하고 각 변수 간의 구분은 쉼표','를 사용함

 

2) 메서드 구현부(method body, 메서드 몸통)

- 메서드 선언부 다음에 오는 괄호 {}

- 메서드를 호출했을 때 수행될 문장 작성

- return문: 메서드의 반환타입이 'void'가 아닌 경우 구현부 안에 반드시 단 하나의 return 반환값이 포함되어야 함 (반환타입이 일치하거나 적어도 자동 형변환이 가능한 것이어야 함)

- 메서드 내에 조건문에서 return문을 작성할 시 가능한 모든 조건에 return문을 작성해야 함

- 지역변수(local variable) : 메서드 내에 선언된 변수로써, 메서드 내에서만 사용이 가능함

 

4. 메서드 호출

 

메서드이름(값1, 값2,...); 

 

1) 인자(argument)와 매개변수(parameter)

- 인자 : 메서드를 호출할 때 괄호()안에 지정해준 값들

- 인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야 함

 

2) 메서드의 실행흐름

- 같은 클래스 내의 메서드 : 참조변수를 사용하지 않고도 서로 호출 가능

- static 메서드 : 같은 클래스 내의 인스턴스 메서드를 호출할 수 없음 (해당 클래스의 인스턴스를 생성한 후 참조변수를 통해 호출해야 함)

 

class Test
	public static void main(String[] args) {
    	Test t = new Test();		// 인스턴스 생성
        int a = 3, b = 5;
        int result = t.calc(a, b):	// 참조변수로 메서드 호출
    }
    
    int calc(int x, int y) {
    	return x + y;
    }
}
    

 

5. JVM의 메모리 구조

 

JVM의 메모리 구조

 

1) 메서드 영역(method area)

- 프로그램 실행 중 어떤 클래스가 사용되면 JVM은 해당 클래스의 클래스파일(*.class)을 읽어서 분석함

- 클래스에 대한 정보(클래스 데이터)를 이곳에 저장함

- 클래스의 클래스변수(class variable)도 이 영역에 함께 생성됨

 

2) 호출스택(call stack 또는 execution stack)

- 메서드 작업에 필요한 메모리 공간 제공

- 메서드가 호출되면, 호출스택에 호출된 메서드를 위한 메모리가 할당됨

- 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용됨

- 메서드가 작업을 마치면 메모리 공간은 반환됨

 

3) 힙(heap)

- 인스턴스가 생성되는 공간

- 프로그램 실행 중 생성되는 인스턴스는 모두 이곳에 생성됨

- 인스턴스변수(instance variable)이 생성되는 공간

 

4) 메서드 호출 흐름

- 각 메서드를 위한 메모리상의 작업공간은 서로 구별됨

- 스택에 호출된 메서드 순서대로 쌓임

- 호출스택의 제일 상위에 있는 메서드가 현재 실행 중인 메서드임

- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드임

- 반환타입(return type)이 있는 메서드는 종료되면서 결과값을 자신을 호출한 메서드(caller)에게 반화함

 

6. 참조형 매개변수와 반환타입

1) 기본형 매개변수와 참조형 매개변수

 

기본형 매개변수  변수의 값을 읽기만 할 수 있음 (read only)
참조형 매개변수  변수의 값을 읽고 변경할 수 있음 (read & write)

 

- 매개변수의 타입이 기본형(primitive type)일 때는 기본형 이 복사

- 매개변수의 타입이 참조형(reference type)일 때는 인스턴스의 주소가 복사

 

// 기본형 매개변수
void change(int x) {
	...
}

// 참조형 매개변수
void change(Date d) {
	...
}

 

2) 참조형 반환타입

- 반환타입도 참조형이 될 수 있음

- 모든 참조형 타입의 값은 '객체의 주소'이므로 정수값이 반환됨

 

// 참조형 반환타입
Data copy(Data d) {
	Data tmp = new Data();
    tmp.x = d.x;
    
    return tmp;
}

 

 

7. 재귀호출(recursive call)

- 재귀호출 : 메서드의 내부에서 메서드 자신을 다시 호출하는 것

- 재귀 메서드 : 재귀호출을 하는 메서드

 

void method() {
	method()
}

 

- 재귀호출엔 조건문이 필수로 함께 쓰임

 

void method(int n) {
    if(n==0) return;
    System.out.println(n);
    
    method(--n);
}

 

 

8. 클래스 메서드(static 메서드)와 인스턴스 메서드

1) 클래스 메서드

- 앞에 static이 붙은 메서드

- 객체를 생성하지 않고 '클래스이름.메서드이름(매개변수)'로 호출 가능

 

2) 인스턴스 메서드

- 반드시 객체를 생성하여 호출

 

클래스 메서드와 인스턴스 메서드의 구분

1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙임

2. 클래스 변수(static변수)는 인스턴스를 생성하지 않아도 사용할 수 있음

3. 클래스 메서드(static메서드)는 인스턴스 변수를 사용할 수 없음

4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려함
( 메서드 호출시간이 짧아져 성능이 향상됨)

 

9. 클래스 멤버와 인스턴스 멤버 간의 참조와 호출

- 같은 클래스의 멤버간은 별도의 인스턴스를 생성하지 않고도 서로 참조 및 호출 가능

 

- 단, 클래스 멤버(변수, 메서드)가 인스턴스 멤버(변수, 메서드)를 참조하는 경우 제외

-> 인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재 but 클래스 멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수도 있기 때문

 

- 인스턴스 멤버간의 호출은 문제 없음

-> 하나의 인스턴스 멤버가 존재한다는 것은 인스턴스가 이미 생성되어 있음을 의미하기 때문

 

 

 

 

 

참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)