# 레퍼런스 변수와 static
## 들어가며
---
이전 시간, 객체를 만드는 특별한 메소드, 생성자에 대해 배웠습니다. 생성자의 역할은 아래와 같았었죠?

이번 시간에는 객체를 가리키는 **레퍼런스 변수**와, 공유의 키워드인 `static`에 대해 알아보도록 하겠습니다.
## 목차
---
1. 레퍼런스 변수
2. 기본형 변수와의 차이
3. static 키워드
4. 클래스 변수
5. 클래스 메소드
## 1. 레퍼런스 변수
---
레퍼런스(reference) 변수란, 클래스 타입의 변수로 *객체를 가리킵니다.*
사실 우리는 레퍼런스 변수를 알게 모르게 사용해왔는데요. 아래 코드에서 변수 b가 바로 레퍼런스 변수입니다. 이를 통해 객체를 사용할 수 있었죠?
```
/* 객체 생성과 동시에 초기화 */
Bicycle b = new Bicycle("부릉2", 21.74, 899000);
```
위 코드를 통해 생성된 객체와 레퍼런스 변수의 관계. 이를 그림으로 표현하면 아래와 같습니다.

객체를 가리키는 레퍼런스변수. 이는 왜 필요하고 또 무엇이 기존 변수와 다른 걸까요?
## 2. 기본형 변수와의 차이
---
**기본형**(primitive) 변수는 객체가 아닌 것을 저장하는 변수로, int, double, boolean, char 등의 고정 크기의 값을 *직접 저장*할 수 있습니다.

하지만 객체는 직접 저장할 수 없죠. 왜죠? 객체는 크기가 너무 크기 때문입니다. 이를 해결하기 위해 나온 개념이 바로 레퍼런스(reference) 변수입니다.
**레퍼런스**(reference) 변수는, 객체를 직접 저장하는 것이 아니라 *객체의 위치를 저장하는 방식* 즉, 객체를 간접적으로 가리키는 방식을 취합니다.

이는 마치, 주소를 따라가면 원하는 장소가 나오는 것과 같은 원리이죠.

그럼 다음으로, static 키워드에 대해 알아볼까요?
## 3. static 키워드
---
static은 “공유”라는 개념을 담은 키워드입니다. 이 키워드는 클래스의 구성요소인 필드와 메소드에 적용될 수 있는데요. 필드에 사용되면 클래스 변수, 메소드에 사용되면 클래스 메소드가 됩니다.

## 4. 클래스 변수
---
**클래스 변수**란, 객체 내부에 존재하는 인스턴스 변수와 달리, 객체 외부인 *클래스 영역에 존재하는 변수*입니다. 여기서 인스턴스 변수란 앞서 배웠던 일반적인 필드의 변수를 뜻하는데요. 이는 말 그대로 **인스턴스 변수** 즉, *객체 내부에 존재하는 변수*입니다. 이와 달리 클래스 변수는 객체 외부에 존재하기 때문에, 다양한 객체들이 서로 공유할 수 있는 장점이 있죠.

클래스 변수는 필드에 static 키워드를 붙여서 선언합니다.
```
// 클래스 변수 count를 0으로 초기화
static int count = 0;
```
아래는 클래스 변수의 선언 예인데요. 실제 코드가 어떻게 동작하는지 분석을 하면 보다 클래스 변수에 대한 이해가 쉽겠죠?
```
class Student {
// 인스턴스 변수
int stdNum; // 학번
String name; // 이름
/*****************
* 클래스(공유) 변수 *
*****************/
static int count = 0;
// 생성자
public Student(String n) {
Student.count++; // 클래스 변수 증가
stdNum = Student.count; // 학번 초기화
name = n; // 이름 초기화
}
}
```
아래 코드를 실제로 수행해보고 어떠한 일들이 발생하는지 스스로 확인해보세요. 자세한 내용은 실습을 통해 또 연습해보도록 하겠습니다.
```
public class StudentTest {
public static void main(String[] args) {
Student tom = new Student("Tom");
Student kate = new Student("Kate");
Student paul = new Student("Paul");
System.out.printf("모든 학생의 수는 %d명 입니다.", Student.count);
}
}
```
계속해서 static을 메소드에 선언하는 경우에 대해 알아볼까요?
## 5. 클래스 메소드
---
클래스 메소드란, 주체 객체 없이 호출 가능한 메소드입니다. `Math.random()`이 그 대표적인 예죠.
```
// 클래스 메소드 호출 예
double rand = Math.random(); // Math 타입을 통한 메소드 호출
```
이와 반면 인스턴스 메소드 즉, 특정 객체가 수행하는 메소드는, 호출 전 반드시 객체가 필요합니다. 아래 예를 보면 레퍼런스 변수에 연결된 Hero 타입의 객체를 통해 메소드를 호출하고 있음을 알 수 있습니다.
```
// 인스턴스 메소드 호출 예
Hero hero = new Hero("닥터 스트레인지", 80); // 주체 객체 생성
hero.teleport(); // 주체 객체를 통한 메소드 호출
```
클래스 메소드는 객체 생성 없이 호출이 가능하기에 편의성면에서 장점이 있는 반면, 주체의 구분이 명확하지 않다는 단점도 존재합니다.
이러한 클래스 메소드는 어떻게 만들 수 있을까요? 간단합니다. 메소드에 `static`을 추가하면 되죠.
```
/* 클래스 메소드 - static 선언된 메소드 */
public static TYPE NAME(PARAMETERS) {
return VALUE;
}
```
## 요약
---
#### 레퍼런스 변수
- 레퍼런스 변수란, 객체를 가리키는 변수다.
- 기본형 변수는 값을 직접 저장하나, 레퍼런스 변수는 객체의 위치를 가리킨다.
#### static 키워드
- static 키워드는 필드와 메소드에 적용될 수 있다.
#### 클래스 변수
- 클래스 변수란, 클래스 영역에 존재하는 변수다.
- 인스턴스 변수란, 객체 내부에 존재하는 변수다.
#### 인스턴스 변수
- 클래스 메소드란, 주체 객체가 없이 수행되는 메소드다.
- 인스턴스 메소드란, 주체 객체가 실행하는 메소드다.
## 확인하기
---
<div class="interact_responsive_padding" style="padding:100% 0 0 0;position:relative;margin-bottom:5px;"><div class="interact_responsive_wrapper" style="height:100%;left:0;position:absolute;top:0;width:100%;"><iframe id="interactApp5ce54fd17bcb600014fd74fa" width="100%" height="100%" style="border:none;max-width:100%;margin:0;" allowTransparency="true" frameborder="0" src="https://quiz.tryinteract.com/#/5ce54fd17bcb600014fd74fa/q/1?method=iframe"></iframe></div></div>