[클래스와 객체]
자바는 객체 지향 언어이다. 객체 지향이란 현실세계를 예시로 들 때 특정한 제품들을 만드려고 할 때
여러 가지 부품들을 이용하고 해당 부품들을 결합하여 하나로 조립하는 과정을 말한다.
애플이라는 회사를 예시로 들 때 아이폰을 만들기 위한 설계도가 있고 해당 설계도를 이용하여 각종 부품들을 구현한다고 칠 때
설계도가 클래스고, 각종 부품들을 객체라고 할 수 있다.
즉 클래스란 제품을 만들기 위한 설계도이고, 객체란 클래스를 통해 만들어낸 제품이라고 할 수 있다.
[인스턴스]
클래스를 통해 객체를 선언하는 과정 할 때의 과정을 인스턴스화라고 한다.
객체와 인스턴스는 의미가 똑같은 것 같지만 사실은 다르다.
쉽게 이해하기 위해 예시를 하나 들어보겠다.
public class Animal {
public static void main(String[] args) {
// Animal의 인스턴스는 tiger 이다.
// tiger는 Animal의 객체이다.
Animal tiger = new Animal();
}
}
해당 파일에는 Animal이라는 클래스가 존재한다.
이때 Animal의 클래스의 tiger라는 객체를 생성하는데 tiger객체는 Animal클래스의 인스턴스이다.
즉 인스턴스는 클래스와의 관계위주로 설명할때 사용된다.
[필드]
필드란 해당 클래스에 존재하는 변수들을 말한다. 다른 말로는 멤버 변수들을 말한다.
해당 필드는 다음과 같은 종류가 있다.
변수 | 생성 시기 | 소멸 시기 | 저장 메모리 |
클래스 변수 | 클래스가 메모리에 올라갈 때 | 프로그램이 종료될 때 | 메소드 영역 |
인스턴스 변수 | 객체가 생성될 때 | 인스턴스가 소멸할 때 | 힙 영역 |
지역 변수 | 블록 내의 코드가 실행될 때 | 블록 내의 코드가 끝날 때 | 스택 영역 |
public class Human {
int instance = 1; // 인스턴스 변수
static int staticinstance = 2; // 클래스 변수
void run() {
int local_instance = 3; // 지역 변수
}
public static void main(String[] args) {
System.out.println("Hi");
}
}
해당 코드를 보았을 때 static이 붙으면 클래스 변수, static이 없다면 인스턴스 변수이다.
일반적으로는 공통적인 값을 사용할 때 클래스 변수를 사용하고, 독립적인 값들을 사용한다면 인스턴스 변수를 사용하면 된다.
지역변수는 블록이 시작될 때 생성되었다가 끝날 때까지 사용되고 블록이 종료된다면 변수의 값도 사라지게 된다.
[객체 생성 과정]
1) 코드가 실행되면서 메인 메서드가 실행된다.
1-1) 해당 메인 메소드에 존재하는 클래스의 구조와 메서드, 변수등의 정보들이 메서드 영역에 저장된다.
2) main메서드가 실행되면서 메인 메서드 영역에 존재하는 클래스의 정보들을 바탕으로 스택 영역에 메서드 호출 스택이 생성된다.
2-1 ) 이때 스택영역에서는 메소드나 각종 작업들이 순차적으로 스택에 올라가게 실행된다.
2-2 ) 스택에 각종 변수와 값들을 읽어 들이면서 지역변수와 매개변수의 인자값을 할당받게 된다.
2-3 ) 해당 값들은 메인 메소드가 종료될 때까지 유지된다.
3) 변수와 값들을 읽어들이면서 스택영역에 지역변수와 매개변수의 값들이 저장된다.
4) 만약 객체가 생성되었다면 객체는 힙(heap) 영역에, 해당 객체를 가리키는 참조변수는 스택(stack) 영역에 저장된다.
글을 보았을때는 잘 이해가 되지 않을 수 있으니 간단한 예시를 들어보겠다.
public class Human {
public static void main(String[] args) {
String shouting = "소리지르기";
int height = 177;
int kg = 70;
Human man = new Human();
}
}
1) main 메서드 부분이 실행되면서 클래스의 구조와 메서드, 변수등의 정보들이 메서드 영역에 저장된다.
2) new라는 연산자를 통해 필드의 값들이 임의의 메모리 공간에 저장된다.
3) Human이라는 클래스의 참조변수인 man을 만든다. 쉽게 생각해서 클래스에 대한 변수라고 생각하면 된다.
4) Human()은 지금은 생성자라는 것을 기본 초기화를 시킨다고 생각하자.
5) 이때 임의의 메모리 공간에 필드의 값들이 저장되어 있는데 그 값들을 man이라는 변수에 저장한다.
이로써 man이라는 변수에 해당 클래스의 값들을 가지고 있는 메모리 주소번지를 저장하게 된다.
즉 man이 객체는 아니고 객체의 주소번지를 가지고 있는 변수라고 생각하면 좋다.
이때 참조변수 man은 스택에 저장되고 실제 필드의 값을 지닌 객체는 힙(heap) 영역에 저장된다.
Human man = new Human();
Human : 클래스
man : 필드의 값을 가지고 있는 메모리 주소번지를 저장.
new : 필드의 값들을 임의의 메모리 공간에 저장.
Human() : 한번 초기화 시켜라.
[매개변수, 인자]
- 클래스 메서드로 구현할 때 -
public class Operator {
public static int add(int value1, int value2) {
return value1 + value2;
}
public static void main(String[] args) {
System.out.println(add(2,5));
}
}
여기서 매개변수는 value1, value2가 매개변수이다.
매개변수란 메서드나 생성자를 선언할 때 들어올 값의 자료형과 그 값을 받을 변수를 생성해 주는 것이다.
사실상 매개변수도 지역변수와 동일하다고 할 수 있다.
add메서드는 값을 연산하는 기능을 한다. 이때 add()라는 메서드를 호출하는데 값이 존재하지 않다.
그래서 내가 원하는 연산을 하기 위해 매개변수에 2, 5라는 값을 넣어주는데 이것을 인자 라고 한다.
코드를 보았을 때 add메서드가 위에 있어서 add메서드가 먼저 실행된다고 생각할 수 있는데 코드가 실행되는 과정을 보자.
1) 클래스파일이 실행되면서 main메서드가 먼저 실행된다.
2) 클래스의 구조와 정보들이 메서드 영역에 저장되면서 println메서드를 실행한다.
3) 이때 add라는 메서드를 호출하게 되는데 인자값으로 2, 5를 준다.
4) add메서드의 매개변수에 int형으로 2, 5가 넘어오게 되고 두 값을 더한 결과가 반환된다.
5) 다시 main메서드에 돌아오면서 7이 반환된다.
위의 코드는 메서드를 클래스 메서드로 만들었기 때문에 main메서드에서 객체를 생성하지 않고 바로 호출해 주었다.
인스턴스 메서드로 구현했을 때는 코드가 어떻게 되는지 알아보자.
- 인스턴스 메서드로 구현할 때 -
public class Operator {
public int add(int value1, int value2) {
int result = value1 + value2;
}
public static void main(String[] args) {
Operator operator = new Operator();
operator.add(2,5);
}
}
클래스 메소드로 구현했을 때와는 다른 점은
1) 해당 클래스의 객체를 생성했다.
2) 객체. 메서드(인자값, 인자값)로 결괏값은 호출해 주었다.
위의 인스턴스 메서드와 클래스 메서드로 구현했을 때는 코드상의 이러한 차이점이 존재하지만 결괏값을 동일하다.
하지만 클래스 메서드는 메서드가 생성되면서 바로 메모리에 올라가기 때문에 인스턴스 메서드를 사용할 때보다는
보다 메모리를 효율적으로 사용할 수 있다는 장점이 있다.
또한 코드가 실행되는 과정이 클래스의 구조와 값들이 먼저 저장되고 객체가 생성되는 순서이기 때문에
클래스 메서드에서는 인스턴스 메소드를 호출할 수 없고, 인스턴스 메소드에서는 객체가 생성됐을 때
클래스의 값들도 생성되어 있기 때문에 호출이 가능하다.
그렇다고 인스턴스 메서드로 사용하는 것이 안 좋은 게 아니라 각 메서드의 특성과 요구사항에 따라 적절히 사용하면 좋다.
[핵심 요약]
- 클래스는 설계도, 객체는 설계도를 이용해 만든 제품
- 필드는 클래스에 존재하는 변수들
- Human man = new Human(); 일 때 man이 참조변수로써 new라는 연산자를 통해 생성된 객체의 메모리의 주소번지를 가리킨다.
- 클래스 메서드는 객체 생성이 필요 X, 인스턴스 메서드는 객체 생성 필요
'스터디 > JAVA' 카테고리의 다른 글
[JAVA] 컬렉션 (1) | 2024.02.18 |
---|---|
[JAVA] Thread (0) | 2024.02.15 |
[JAVA] 상속 (0) | 2024.02.12 |
[JAVA] 배열 (1) | 2024.02.07 |
[JAVA] 변수와 타입 (0) | 2024.01.29 |