Abstraction
: 추상화Polymorphism
: 다형성Inheritance
: 상속Encapsulation
: 데이터 은닉과 보호OOP
: Object Oriented Programming객체
객체지향 프로그래밍
“그렇다면 객체지향은 객체를 많이 만드는 것을 선호하는 것일까?”
그렇지는 않다. 객체를 너무 많이 만들게 되면 코드가 복잡해지고 유지보수가 어려워질 수가 있다. 또한 메모리 사용량이 증가하고, 객체 간 의존성이 증가하게 되어 결합도가 올라갈 수 있다.
그렇기에 객체를 무작정 많이 만드는 것이 아니라 객체 간의 관계를 잘 설계하는 것이 중요하다. OOP의 핵심은 객체 개수가 아닌, 객체 간의역할
과협력
이기 때문이다.
신뢰성
이 높은 프로그램을 할 수 있다.유연하고 유지보수
에 용이하다.재사용성
이 높다.추상화
되어 클래스에 정의된다.구체화
되어 프로그램의 객체(Instance, Object)가 된다.설계도
, 객체는 그러한 설계도를 통해 나온 제품
이라고 이해할 수 있다.JVM(Java Virtual Machine)
은 메모리를 효율적으로 관리하고 실행할 수 있도록 특정한 메모리 구조를 사용한다.JVM 메모리 구조
구분 | 설명 |
---|---|
1. 메서드 영역(Method Area, 클래스 영역) | 클래스(정적 데이터), 인터페이스, 메서드 코드, 상수 풀 등이 저장됨 |
2. 힙(Heap) | 객체(인스턴스)와 배열이 저장됨 |
3. 스택(Stack) | 메서드 호출 시 지역 변수, 매개변수, 리턴 값 등이 저장됨 |
4. PC 레지스터(PC Register) | 현재 실행 중인 JVM 명령어의 주소를 저장 |
5. 네이티브 메서드 스택(Native Method Stack) | C/C++ 같은 네이티브 코드 실행 시 사용 |
1. 메서드(Method) 영역 (클래스 영역)
final
, 인터페이스 메서드, 클래스의 메서드 코드 등이 들어간다.public class Movie {
static String category = "Film"; // 메서드 영역에 저장 (static 변수)
}
2. 힙(Heap) 영역
new
키워드로 생성한 모든 객체가 여기에 저장된다.Movie m1 = new Movie(); // Heap 영역에 저장
3. 스택(Stack) 영역
public void printMovie(String title) {
int duration = 120; // Stack 영역에 저장
}
public class MemoryExample {
static String category = "Film"; // 메서드 영역 (Method Area)
public static void main(String[] args) {
int x = 10; // 스택 (Stack)
Movie m1 = new Movie(); // 힙 (Heap)
}
}
변수 종류 | 선언 위치 | 특징 |
---|---|---|
인스턴스 변수 (Instance Variable) | 클래스 내, 메서드 외부 | 객체 생성 시 초기화, 객체가 참조되지 않으면 가비지 컬렉션 대상 |
클래스 변수 (Static Variable) | 클래스 내, static 키워드 사용 | 프로그램 시작 시 초기화, 모든 객체가 공유, 클래스가 메모리에 로드될 때 초기화 |
지역 변수 (Local Variable) | 메서드, 생성자, 초기화 블록 내부 | 메서드 호출 시 생성, 메서드 종료 시 소멸, 초기화 필요가 |
new
키워드로 객체를 만들 때이다.public class Car {
String color; // 인스턴스 변수
int speed; // 인스턴스 변수
}
static
키워드를 사용한다.ClassName.variable
)public class Car {
static int totalCars; // 클래스 변수 (모든 Car 객체가 공유)
public Car() {
totalCars++; // 객체 생성 시마다 증가
}
}
public void drive() {
int distance = 100; // 지역 변수
System.out.println("Driving " + distance + " km");
}
프로그래밍화
한 것이다.묵시적 형변환
이 적용된다.public void addAll(int... nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
}
static member
는 항상 메모리에 있기 때문에, 클래스명.멤버명
으로 다른 클래스에서도 어디서든 호출이 가능하다.instance member
는 객체를 생성하기 전에는 메모리에 없기 때문에, 우선 객체를 생성한 후에 객체(=레퍼런스)를 통해 접근할 수 있다.Call Stack
은, FILO 구조
즉 후입선출 방식
으로 동작한다. 그 이유는 아래와 같다.재귀 호출과 메서드 실행 흐름을 자연스럽게 관리하기 위함이다. 만약 먼저 호출된 메서드가 먼저 종료된다면, 이후 메서드가 정상적으로 작동하지 않을 가능성이 발생한다.
스택 구조는 메서드 실행이 끝나면 자동으로 메모리를 해제할 수 있다. 때문에 필요하지 않은 메서드의 지역 변수를 빠르게 제거할 수 있어 메모리 누수를 방지한다.
→ FIFO 구조인 큐
는 힙 메모리
를 사용하기 때문에, 큐에서 꺼내 메모리 호출을 한다고 해도 GC
가 메모리를 해제해주어야 한다.
스택(Stack) 메모리 | 힙(Heap) 메모리 | |
---|---|---|
사용 대상 | 메서드 호출, 지역 변수, 매개변수 | 실행 중 유지되어야 하는 객체 |
메모리 해제 방식 | 메서드 종료 시 자동 해제 | GC(가비지 컬렉터)가 해제 |
속도 | 빠름 (메모리 접근 속도 높음) | 상대적으로 느림 (GC가 필요) |
데이터 크기 | 고정 크기 (메서드 실행 중 유지) | 동적으로 변경 가능 |
대표적인 구조 | 스택(Stack) | 큐(Queue), 리스트(List), 트리(Tree) 등 |
멀티스레드 환경에서의 안정적인 실행을 위함이다. 각 스레드는 자신만의 스레드를 갖고 있기 때문에 독립적인 실행이 가능하다.
오버로딩
이 가능하다.JVM의 메모리구조에 대해 학습할 수 있었다. 특히, 스택과 힙 메모리 영역의 차이점에 대해 더 잘 알 수 있었다.
변수의 종류와 차이점을 확실히 알게 되었다.
메서드 호출 스택은 LIFO 구조, 즉 스택 방식이라는 사실을 알게 되었다. 또한 그 이유에 대해서도 탐구하며 납득할 수 있었다.
기본 생성자와 생성자가 없을 시 컴파일러가 자동으로 기본 생성자를 추가한다는 사실을 알 수 있었다.