클래스란
객체란
예제
new라는 키워드를 사용합니다.public class Person(){
...
}
public class Main {
public static void main(String[] args) {
Person personA = new Person(); // 첫 번째 객체 생성
Person personB = new Person(); // 두 번째 객체 생성
}
}
클래스 구조
class 클래스{
// ✅ 속성
// ✅ 생성자
// ✅ 기능
}
속성
class Person {
// ✅ 속성
String name;
int age;
String address;
}
속성에 접근
객체를 통해 속성에 접근할 때 객체가 담긴 변수.속성으로 접근합니다.
객체마다 속성 값이 다를 수 있습니다.
public class Main {
public static void main(String[] args) {
// ✅ 객체 생성
Person personA = new Person();
Person personB = new Person();
// ✅ 객체를 통해 접근 personA 의 name
System.out.println(personA.name);
// ✅ 객체를 통해 접근 personB 의 name
System.out.println(personB.name);
}
}
생성자
기본 생성자
public class Person {
Person() {} // ✅ 기본 생성자 자동추가, 보이지 않습니다.
}
생성자의 특징
생성자를 활용한 객체
public class Person {
String name;
int age;
String address;
Person() {} // ❌ 기본생성자 제거됨
Person(String name, int age) { // ✅ 새로운 생성자(조립설명서)
this.name = name;
this.age = age;
}
}
public class Main {
public static void main(String[] args) {
Person personA = new Person("gygim", 10); // ✅ 조립설명서 준수
Person personB = new Person("Steve", 5); // ✅ 조립설명서 준수
}
}
this 키워드
this는 객체 자신을 가리키는 키워드입니다. 현제 실행 중인 객체를 의미합니다.기능
class Person {
...
// ✅ 사람의 소개 기능
void introduce() {
System.out.println("안녕하세요.");
System.out.println("나의 이름은 " + this.name + "입니다.");
System.out.println("나이는 " + this.age + "입니다.");
}
// ✅ 사람의 더하기 기능
int sum(int a, int b) {
int result = a + b;
return result;
}
}
public class Main {
public static void main(String[] args) {
Person personA = new Person("gygim", 10);
personA.introduce(); // ✅ personA 객체 introduce() 호출
Person personB = new Person("Steve", 5);
}
}
게터
String getName() {
return this.name;
}
int getAge() {
return this.age;
}
String getAddress() {
return this.address;
}
String name = person.getName();
int age = person.getAge();
String address = person.getAddress();
세터
void getName(String name) {
this.name = name;
}
void getAge(int age) {
this.age = age;
}
void setAddress(String address) {
this.address = address;
}
public class Main {
public static void main(String[] args) {
Person personA = new Person("gygim", 20);
Person personB = new Person("Steve", 15);
personA.setAddress("서울"); // ✅ personA 의 주소 설정
personB.setAddress("미국"); // ✅ personA 의 주소 설정
}
}
JVM 메모리 구조

Method Area
Stack Area
Heap Area
new 키워드로 생성된 객체가 저장되는 곳입니다.코드 흐름
public class Main {
static class Person {
// 1. 속성
String name;
int age;
String address;
// 2. 생성자
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 3-1. 소개 기능(이름 나이 출력 기능)
void introduce() {
System.out.println("나의 이름은");
System.out.println(this.name + "입니다.");
System.out.println("나의 나이는");
System.out.println(this.age + "입니다.");
}
// 3-2. 더하기 기능(소개를 하고 더하기 연산 수행)
int sum(int value1, int value2) {
introduce();
int result = value1 + value2;
return result;
}
}
public static void main(String[] args) {
String name = "Steve";
int age = 20;
Person personA = new Person(name, age);
personA.introduce();
int value1 = 1;
int value2 = 2;
int ret = personA.sum(value1, value2);
System.out.println(ret);
}
}
Method 이해하기
Heap 이해하기
new 키워드로 생성된 객체는 Heap영역에 저장됩니다.Stack 이해하기
public class Main {
public static void main(String[] args) {
String name = "Steve"; // 1
int age = 20;
Person personA = new Person(name, age); // personA = @100호
personA.introduce(); // 2
}
}
래퍼클래스란
| 기본 자료형 (Primitive Type) | 래퍼 클래스 (Wrapper Class) |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
참조형
Person personA = new Person("Steve"); // ✅ 객체가 담긴 personA 는 참조형 변수입
Syetem.out.println(personA.name);
System.out.println(personA); // ✅ 출력하면 @123 메모리의 주소값이 출력됩니다.
int[] arr = {1, 2, 3, 4}; // ✅ 배열이 담긴 arr 는 참조형 변수입니다.
System.out.println(arr); // ✅ 출력하면 @123 메모리의 주소값이 출력됩니다.
래퍼클래스&객체
Integer num = 100;
System.out.println(num); // ✅ 출력 100
toString()이 오버라이딩 되어 있기 때문입니다.래퍼클래스 사용 이유
Integer num = 123; // 래퍼클래스
String str = num.toString(); // ✅ 편리한 기능
int a = 100; // 그냥 데이터 100
String str = a.toString(); // ❌ 변환 불가
커스텀 래퍼클래스
class CustomInteger {
// ✅ 속성
int value;
// ✅ 생성자
CustomInteger(int value) {
this.value = value;
}
// ✅ 기능
// ✅ 값을 가져오는 메서드
int getValue() {
return value;
}
// ✅ 값을 설정하는 메서드
void setValue(int value) {
this.value = value;
}
// ✅ toString() 오버라이딩 (값을 출력할 수 있도록)
@Override
public String toString() {
return String.valueOf(value);
}
}
public class Main {
public static void main(String[] args) {
CustomInteger num1 = new CustomInteger(100);
System.out.println(num1); // ✅ 100
System.out.println(num1.getValue()); // ✅ 100
num1.setValue(200);
System.out.println(num1); // ✅ 200
}
}
오토 박싱&언박싱
Integer num3 = 10; // ✅ 오토박싱 (기본형을 자동으로 래퍼 클래스 객체로 변환)
int num = num3; // ✅ 오토 언박싱(참조형을 자동으로 기본형으로 변환)
오토박싱
Integer는 참조형(객체)이지만 기본형 int값을 직접 대입할 수 있습니다.Integer.valueOf(10)을 호출하여 객체를 생성하기 때문입니다.Integer num3 = 10; // ✅ 오토박싱
// ✅ 내부적 자동 처리(래퍼형 <- 기본형)
Integer num = Integer.valueOf(10);
오토 언박싱
num은 Integer객체(참조형변수)지만 기본형 int변수에 대입할 수있습니다.num.intValue()를 호출하여 기본형으로 변환하기 때문입니다.Integer num3 = 10;
int num = num3; // ✅ 오토 언박싱
// ✅ 내부적 자동처리(기본형 <- 래퍼형)
int a = num.intValue();
기본형과 래퍼형 성능 비교
static이란
static 활용
class Person {
// ✅ static 변수
static int population = 0;
// ✅ static 메서드
static void printPopulation() {
System.out.println("현재 인구 수: " + population);
}
}
System.out.println("static 변수: " + Person.population);
System.out.println("static 메서드: " + Person.printPopulation);
인스턴스 멤버
인스턴스 변수
name 변수는 각 객체마다 별도로 저장됩니다.class Person {
String name; // ✅ 인스턴스 변수
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person(); // p1 객체 생성
p1.name = "gygim"; // ✅ p1 객체의 데이터에 접근
Person p2 = new Person(); // p2 객체 생성
p2.name = "Steve"; // ✅ p2 객체의 데이터에 접근
}
}
인스턴스 메서드
class Person {
String name;
void printName() { // ✅ 인스턴스 메서드
System.out.println("나의 이름은 " + this.name + "입니다.");
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "gygim";
p1.printName(); // ✅ p1 객체의 메서드 실행
Person p2 = new Person();
p2.name = "Steve";
p2.printName(); // ✅ p2 객체의 메서드 실행
}
}
클래스 멤버
클래스 변수
클래스명.변수명으로 접근 가능합니다.class Person {
static int population = 0; // ✅ 클래스 변수
}
public class Main {
public static void main(String[] args) {
// ✅ 객체 생성 전에도 클래스 레벨에서 직접 접근가능
System.out.println("현재 인구 수: " + Person.population);
Person p1 = new Person();
Person p2 = new Person();
// ✅ 모든 객체가 하나의 값을 공유
System.out.println("현재 인구 수: " + Person.population);
}
}
클래스 메서드
class Person {
static int population = 0;
public Person(String name) {
this.name = name;
population++; // 생성자 호출시 populataion 1 증가
}
static void printPopulation() {
System.out.println("현재 인구 수: " + population); // ✅ 클래스 메서
}
}
public class Main {
public static void main(String[] args) {
// ✅ 객체생성 여부에 상관없이 사용 가능
Person.printPopulation(); // 현재 인구 수: 0
Person p1 = new Person("gygim"); // 생성시마다 population 1 증가
Person p2 = new Person("Steve"); // 생성시마다 population 1 증가
Person.printPopulation(); // 현재 인구 수: 2
}
}
static 변수와 메모리는 프로그램이 종료될 때까지 메모리에 유지됩니다.
필요할 때만 사용해야 합니다.
final의 용도
final int a = 100;
a = 200; // ❌ 오류 발생!
final class Animal {
void sound() {
System.out.println("Animal sound!");
}
}
// class Dog extends Animal {} // ❌ 오류! final 클래스는 상속할 수 없습니다.
class Parent {
final void show() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
@Override
void show() { // ❌ 오류! final 메서드를 재정의할 수 없음
System.out.println("Hello from Child");
}
}
상수
public class Circle {
final static double PI = 3.14159; // ✅ 상수 선언
}
System.out.println("상수활용: " + Circle.PI);
static으로 선언하는 이유
불변객체
final을 속성(property, field)에 활용합니다.public final class Circle {
final static double PI = 3.14159;
final double radius; // ✅ final 로 선언해서 값이 변경되지 않도록 합니다.
Circle(double radius) {
this.radius = radius;
}
}
public final class Circle { // ✅ 클래스에 final 선언 (상속 방지)
private static final double PI = 3.14159; // ✅ 상수는 private static final로
private final double radius; // ✅ 필드를 private final로 선언하여 완전한 불변
public Circle(double radius) { // ✅ 생성자는 public으로 유지
this.radius = radius;
}
public double getRadius() { // ✅ public 메서드로 변경
return radius;
}
public double getArea() { // ✅ public 메서드로 변경
return PI * radius * radius;
}
public double getPerimeter() { // ✅ public 메서드로 변경
return 2 * PI * 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, 새 객체 생성
}
}
인터페이스란
인터페이스의 사용 이유
인터페이스 활용
implements키워드로 인터페이스를 활용할 수 있습니다.interface Car {
void drive();
void stop();
}
class LuxuryCar implements Car {
@Override
void drive() { // ✅ 인터페이스 규칙 준수
System.out.println("멋지게 이동합니다."); // 구현 내용은 자유롭습니다.
}
@Override
void stop() { // ✅ 인터페이스 규칙 준수
System.out.println("멋지게 정지합니다."); // 구현 내용은 자유롭습니다.
}
void charge() { // 🎉 CarA 만의 기능을 확장 가능합니다.
System.out.println("차량을 충전합니다");
}
}
class SpeedCar implements Car {
@Override
void drive() { // ✅ 인터페이스 규칙 준수
System.out.println("빠르게 이동합니다."); // 구현 내용은 자유롭습니다.
}
@Override
void stop() { // ✅ 인터페이스 규칙 준수
System.out.println("빠르게 정지합니다."); // 구현 내용은 자유롭습니다.
}
void autoParking() { // 🎉 CarB 만의 기능을 확장 가능합니다.
System.out.println("자동 주차 기능을 실행합니다.");
}
}
public class Main {
public static void main(String[] args) {
LuxuryCar car1 = new LuxuryCar();
SpeedCar car2 = new SpeedCar();
// ✅ 각 차량의 공통 기능
car1.drive();
car1.stop();
car2.drive();
car2.stop();
// ✅각 차량의 고유 기능
car1.charge();
car2.autoParking();
}
}
인터페이스 다중 구현
implements 키워드로 다수의 인터페이스를 구현할 수 있습니다.// 🚀 "동물의 기본 기능" 인터페이스
interface Animal {
void eat();
}
// ✈ "나는 기능" 인터페이스
interface Flyable {
void fly();
}
// ✅ 다중 구현
class Bird implements Animal, Flyable {
public void eat() {
System.out.println("새가 먹이를 먹습니다.");
}
public void fly() {
System.out.println("새가 하늘을 납니다.");
}
// 추가적으로 land() 메서드도 가능하지만 필수는 아님
public void land() {
System.out.println("새가 착륙합니다.");
}
}
// 실행 코드
public class Main {
public static void main(String[] args) {
Bird bird = new Bird();
bird.eat(); // "새가 먹이를 먹습니다."
bird.fly(); // "새가 하늘을 납니다."
bird.land(); // "새가 착륙합니다."
}
}
인터페이스 다중상속
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("새가 착륙합니다.");
}
}
// 5. 실행 코드
public class Main {
public static void main(String[] args) {
Bird bird = new Bird();
bird.eat(); // "새가 먹이를 먹습니다."
bird.fly(); // "새가 하늘을 납니다."
bird.land(); // "새가 착륙합니다."
}
}
인터페이스에 변수를 선언하는 경우
public static final로 선언됩니다.static 으로 선언되기 때문에 구현체 없이도 활용 가능합니다.public interface Config {
int POPULATION = 100; // public static final 로 선언됩니다.
}
public class Main {
public static void main(String[] args) {
System.out.println(Config.POPULATION);
}
}