
2-1 클래스의 객체
클래스(class)란? - 객체를 만들 때 필요한 청사진
객체(object)란?
- 컴퓨터, 계산기, 자동차 같은 사물들이 객체
- 어떤 개념이나 논리 같은 것들도 객체가 될 수 있음
- 덧셈,뺄셈 등 눈에 보이지 않은 것들도 무형의 객체가 될 수 있음
- 클래스가 준비되어 있으면 클래스를 기준으로 여러 객체들을 만들어 낼 수 있음
Person.class

- 클래스는 객체를 만들기 위한 설계도
- Person 클래스는 사람 객체를 만들기 위한 설계도
- 객체를 만들 때 new라는 키워드를 사용
- 객체를 만드는 과정을 인스턴스화 라고 표현
- 인스턴스화가 되면 Java 메모리 상에 객체가 만들어짐
클래스 구조(생성, 생성자, 기능)
- 클래스 구조는 1. 속성, 2. 생성자, 3. 기능 부분으로 나누어짐
- 속생기라고 외우면 편함
속성

생성자(Constructor) - 조립설명서
- 객체를 만들 때 사용
- 객체를 어떻게 만들지 정의해 놓는 것(조립설명서)
- 생성자가 없으면 클래스를 객체화 시킬 수 없음 (조립 불가)

- Person() {} = 기본생성자는 class 생성시 만들어지지만 우리 눈에 보이지 않음
- 생성자를 정의한 순간 기본 생성자는 사라짐
생성자의 특징
- 클래스와 이름이 같음
- 반환 타입이 존재하지 않음
- 여러개가 존재할 수 있음
this 키워드
- this는 객체 자신을 가리키는 키워드
- 현재 실행중인 객체를 의미
기능

- 기능은 메서드로 표현
- 상상하는 모든 기능 구현 가능
→ ex) 자기소개, 더하기, 걷기 기능 등
- 클래스와 관련된 기능을 작성하는 것이 좋음
- 메서드를 활용하는 것이 객체의 기능을 활용하는 것
게터, 세터(Getter, Setter)

게터(Getter) – 속성을 가져오는 기능
세터(Setter) – 속성을 설정해주는 기능
2-2 JVM 메모리 영역
Java 메모리 구조는 크게 3가지로 나눔
- Method Area ( 도서관처럼 책들이 정리되어있는 책장 같은 느낌이라 생각하면 됨)
- Stack Area (접시 쌓기구조, 프로그램 실행 흐름에 따라 호출된 매서드들이 실행 순서대로 쌓이기도 하고 빠져나가기도 함, 접시처럼 위에부분부터 빠져나감 아래부터 뺄 수 없음 )
- Heap Area(객체가 저장되는 공간, 객체는 크기가 다 다름)
Method(static) 이해하기
- 프로그램이 실행되면 작성했던 모든 파일의 데이터가 Method(static)영역에 저장
- 프로그램 실행 시점에 한번만 저장
- Method 영역에 저장된 데이터는 프로그램 전체에서 공용으로 활용 가능
Heap영역 이해하기
- new 키워드로 생성된 객체는 Heap 영역에 저장

- Stack 영역의 변수가 Heap 영역의 객체를 참조 ( 화살표 → 로 가리키고 있는 모습)
Stack 영역 이해하기
- 메서드가 호출될 때마다 Stack 영역에 메모리가 쌓임
- 접시를 쌓듯이 LIFO-후입선출 구조
- 메서드가 시작되면 추가되고 메서드가 종료되면 사라지는 구조
- 특정 메서드가 실행되면 해당 메서드의 정보의 변수가 Stack에 저장되고 메서드 실행이 끝나면 그 메모리는 자동으로 제거
- 메서드 내에 선언된 지역변수들이 저장되는 공간 → 변수에 객체가 담기면 객체의 주소값이 저장
2-3 레퍼클래스(기본형 참조형)
래퍼클래스(Wrapper Class)란?
- 기본자료형을 객체로 감싸는 클래스

기본형(Prinitive Type)의 종류

참조형(Reference Type)
- 변수에 객체가 담기면 해당 변수를 참조형변수라고 함
- 참조형 변수는 데이터가 저장된 메모리 주소를 가르킴
→ Heap 메모리 주소
- 객체 데이터는 Heap 영역에 저장되어 있기 때문
- 객체, 배열 등이 참조형에 속함

- 빨간네모박스안에 있는 값이 메모리에 주소값
래퍼클래스도 객체
- 래퍼클래스가 담겨 있는 변수도 참조형 변수
- 출력시 메모리 주소값이 나오지 않음

- 내부적으로 toString()이 오버라이딩 되어 있어 메모리 주소값이 아닌 숫자가 출력 됨
왜 래퍼클래스를 사용할까?
- 기본형은 객체처럼 속성, 기능을 가질 수 없음
- 객체는 기능 제공 가능
- 기본형을 감싼 객체를 만들어 기능을 제공하면 편리하게 데이터처리 가능
래퍼클래스 코드

오토방식 VS 언박싱
- 래퍼클래스 ↔ 기본형으로 형변환이 자주 일어남
- Java에서는 형변환 과정을 자동으로 지원
오토박싱(Auto-boxing)
- 기본형 → 래퍼형으로 변환하는 과정을 오토박싱
- Integer는 참조형(객체)이지만 기본형 int 값을 직접 대입 가능
- 내부적으로 컴파이러가 자동으로 Integer.valueOf(10)을 호출하여 객체를 생성하기 때문

오토 언박싱
- 래퍼형 → 기본형으로 변환하는 과정
- num은 Integer 객체(참조형변수)지만 기본형 int 변수에 대입 가능
- 내부적으로 컴파일러가 자동으로 num.intValue()를 호출하여 기본형으로 변환하기 때문

기본형과 래퍼형 성능 비교
- 래퍼형은 내부적으로 데이터를 감싸고 있기 때문에 연산시 불리
- 객체에서 기본형 값을 꺼내서 연산하는 추가작업이 발생하기 때문
- 추가 작업 때문에 기본형보다 래퍼클래스는 연산 속도가 느림
- 빠른 작업이 필요한 경우 기본형을 직접 활용하는 것이 좋음

2-4 : static – 클래스가 공유하는 공간
Static 란
- static 키워드는 모든 객체가 함께 사용하는 변수나 메서드(기능)를 만들 때 사용
- 객체(인스턴스)를 만들지 않아도 클래스 이름만으로 바로 사용 가능
- 모든 객체가 같은 값을 공유
→ 공용게시판이라고 생각하면 이해하기 쉬움
- static 변수와 메서드는 한 번만 생성되고 Method Area(메서드 영역)에 저장
Static 활용
- static 키워드는 변수, 메서드에 붙일 수 있음
- static 키워드로 선언된 변수와 메서드는 MethodArea에 저장
- 각 개체(인스턴스)는 클래스 영역에 저장된 데이터 활용 가능

- 객체 생성안하고 클래스 레벨에 접근해서 바로 사용 가능
- 프로그램 실행시점에 클래스에 대한 정보가 메서드 영역에 저장되서 바로 활용 가능
인스턴스 멤버(인스턴스 변수 + 인스턴스 메서드)
- 객체를 만들때마다 생성되는 변수와 메서드 임
- 객체(인스턴스)를 생성한 후에만 사용 가능
- 각 객체가 개별적으로 값을 가짐(공유되지는 않음)
- 인스턴스는 Heap 영역에 위치
인스턴스 변수란
- 객체가 생성될 때마다 따로 만들어지는 변수
- 객체를 생성한 후 접근 할 수 있음
- name변수는 각 객체마다 별도로 저장
인스턴스 메서드란
- 객체의 속성을 활용하는 메서드
- 객체가 생성된 후에만 사용 가능
인스턴스 멤버 실습

- 인스턴스 멤버, 변수는 객체를 생성하기 전에 활용 불가
- 인스턴스 메서드와 변수는 각 객체가 고유로 가지고 있는 기능임
클래스 멤버 (클래스 변수 + 클래스 메서드)
- 클래스 자체에 속하는 변수와 메서드를 의미
- static 키워드에 사용해서 선언
- 해당 클래스로 만들어진 객체가 공유해서 사용할 수 있음
- 클래스가 로드될 때 Method Area에 적재
- 객체 생성 없이 사용 가능
클래스 변수란
- 클래스가 로드될 때 한 번만 생성
- 모든 객체가 공유하는 변수
- Heap이 아니라 Method Area에 저장
- 객체를 만들지 않아도 클래스명.변수명으로 접근가능
클래스 메서드란
- 클래스에 속하는 메서드
- 객체 없이 사용 가능
- 클래스 변수만 사용 가능, 인스턴스 변수는 사용 불가
클래스 멤버 실습

Static 사용시 주의사항
- 클래스 변수 사용시 주의 사항
→ Static은 공유가 필요한 곳에 사용해야함
- Static 메서드에서 인스턴스 변수에 접근
→ Static 메서드에서는 인스턴스변수에 접근 불가
→ 인스턴스 멤버를 사용하기 위해서는 먼저 객체가 생성되어야 함
→ 객체 생성없이 사용할 수 없음, 접근도 당연히 불가
2-5 final – 변하지 않는 값
final의 용도
- 변수에서 final
- 변수에 final을 붙이면 변수를 한 번만 설정 가능

- 클래스에서 final
- 메서드에서 final
- final로 선언된 메서드는 오버라이딩 할 수 없음
- 자식입장에서 부모에 기능을 다시 재정의 할 수 없음
상수(Constant)
- 변하지 않고 항상 일정한 값을 갖는 수
- Java에서 상수는 대문자로 표현하는 것이 관례
- 프로그램 실행중에 절대 변경되서는 안되기 때문에 static final 키워드를 사용해 선언
- static으로 선언된 변수는 프로그램 시작시 한 번만 초기화되고 모든 인스턴스에서 같은 값을 공유
대표적인 상수 예시 : PI(원주율)
- 원의 넓이, 둘레를 구할 때 공통으로 사용되는 값(변경되면 안됨)

static으로 선언하는 이유(복습)
- 보통 상수는 여러 곳에서 값을 공유해 쓰일 목적으로 활용
- 인스턴스 변수를 static 없이 선언할 경우 인스턴스마다 PI 값이 중복 저장
static없이 선언할 경우

- 인스턴스를 생성할 때 class기반으로 생성된 각 인스턴스들은 c1 c2 c3에 값을 가지게 됨
- 중복된 값을 사용하는건 공용이 아니여서 올바른 상수 활용법이 아님
상수 활용 법

불변객체(Immutable Object)
- 불변객체는 내부 상태를 변경할 수 없는 객체
- final을 속성(property,field)에 활용
- 세터(setter)없이 설계
- 변경이 필요한 경우 새로운 객체를 만들어야 함
→ ex) String, Integer, 래퍼클래스 등
잘못된 불변객체 사용
- final은 참조 변경을 막지만 내부상태 변경은 막지 않음

public class Circle {
final static double PI = 3.14159; // ✅ 직접 만든 원주율 상수
double radius; // ⚠️ final 로 선언되어 있지 않기 때문에 외부에서 변경 가능
Circle(double radius) {
this.radius = radius;
}
}
final Circle c1 = new Circle(2);
c1 = new Circle(3); // ❌ final은 변수 c1이 한 번 참조한 객체는 다른 객체로 변경될 수 없음을 의미함 (참조 불변)
// 하지만 객체 내부의 속성 값은 변경 가능 (불변 객체가 아님)
c1.radius = 3; // ⚠️ 내부 상태 변경 가능 (객체 자체가 불변이 아님)
올바른 불변 객체 활용
- 속성을 final로 서언해 줌
public final class Circle {
final static double PI = 3.14159;
final double radius; // ✅ final 로 선언해서 값이 변경되지 않도록 합니다.
Circle(double radius) {
this.radius = radius;
}
}
불변 객체의 값이 변경이 필요한 경우
- 불변성을 유지하면서 값을 변경하는 효과를 어을 때 활용
- 기존 객체의 상태를 직접 변경할 수 없기 때문에 새로운 객체를 생성
- 생성자를 새로 호출하거나 아래의 기능을 활용

public final class Circle {
public static final double PI = 3.14159;
private final double radius;
public Circle(double radius) {
this.radius = radius;
}
// ✅ 반지름이 다른 새로운 Circle 생성 (불변 객체 유지)
public Circle changeRadius(double newRadius) {
return new Circle(newRadius); // 생성자 호출: 기존 객체 변경 X, 새 객체 생성
}
}
2-6 인터페이스 – 표준화의 시작
인터페이스(interface)란
- 설계 표준
- 클래스가 따라야할 최소한의 공동 규칙을 정의하는 역할
인터페이스 사용하는 이유
- 모든 설계에 표준이 있는 이유와 같음
- 개발자마다 서로 다른 방식으로 메서드를 만든다면 일관성이 깨질 수 있음
- 인터페이스를 활용해서 최소한의 규격을 정의
- 세부 구현은 각 클래스에 맡김
- 일관성을 유지하면서 클래스가 고유한 특색을 확장할 수 있도록 도움
자동차 예시
- LuxuryCar 와 SpeedCar 모두 자동차를 구현하고 있습니다.
- LuxuryCar 를 이용하는 경우 move() 메서드로 주행할 수있지만
- SpeedCar 를 이용하는 경우 drive() 메서드를 활용해 주행해야합니다.
인터페이스 적용
- 모든 클래스가 지켜야 할 최소한의 규칙을 정의
- 클래스에서 implements 키워드로 인터페이스를 활용할 수 있음
- 인터페이스를 구현한 클래스를 구현체라고 함
인터페이스 실습

- LuxuryCar, SpeedCar

- Main, interface
인터페이스의 다양한 기능
인터페이스 다중구현(multi-implementation)
- implements 키워드로 다수의 인터페이스를 구현 가능
- 한 개의 클래스가 여러 인터페이스(animal, flyable)를 구현한 경우 다중구현이라고 함

인터페이스 다중상속(multi-inheritance)
- extends 키워드로 상속을 구현할 수 있음
// 1. 기본 인터페이스: 동물의 기본 기능
interface Animal {
void eat();
}
// 2. 추가 인터페이스: 나는 기능
interface Flyable {
void fly();
}
// 3. ✅ 다중 상속새로운 인터페이스: 동물 + 나는 기능
interface FlyableAnimal extends Animal, Flyable {
void land(); // 추가 기능
}
// 4. 새 클래스 (FlyableAnimal을 구현)
class Bird implements FlyableAnimal {
public void eat() {
System.out.println("새가 먹이를 먹습니다.");
}
public void fly() {
System.out.println("새가 하늘을 납니다.");
}
public void land() {
System.out.println("새가 착륙합니다.");
}
}
인터페이스에 변수를 선언하는 경우
- 변수 선언시 형식에 관계 없이 자동으로 상수로 선언
- public static final로 선언
- static으로 선언되기 때문에 구현체(인터페이스를 구현한 클래스) 없이도 활용 가능
- 인터페이스는 표준의 역할임으로 변수선언은 최소화하는 것이 좋음

잘 봤습니다만 초심을 찾아주세요..