클래스와 객체

현서·2025년 5월 22일
1

자바

목록 보기
8/32
post-thumbnail

1. 객체지향 프로그래밍 (Object-Oriented Programming, OOP)

현실 세계를 객체(object)라는 단위로 모델링하여 프로그램을 구성하는 방식.
코드의 재사용성과 확장성을 높여줌.

객체는 데이터(속성)와 그 데이터를 처리하는 함수(메서드)를 함께 가지며, 클래스(class)를 통해 설계되고 인스턴스를 통해 사용된다.

객체지향의 주요 특징 : 캡슐화, 상속, 다형성, 추상화

2. 클래스(Class)

객체를 만들기 위한 설계도.
객체의 속성과 동작을 정의하는 사용자 정의 자료형이다.

클래스는 변수(필드, 속성)와 메서드(함수)를 포함하여 하나의 단위로 묶으며, 이를 바탕으로 실제 사용할 수 있는 객체(인스턴스)를 생성할 수 있다.

1. 클래스의 구성 요소

필드(Field) 객체가 가지는 변수, 속성 (ex: 이름, 나이 등)
메서드(Method) 객체가 할 수 있는 동작, 함수
생성자(Constructor) 객체가 생성될 때 호출되는 특수한 메서드

package lesson03;

public class Ex02_Dog {
    String name;
    int age;

    public void bark(){
        System.out.println(name + "가 멍멍 짖습니다.");
    }

    public void introduce(){
        System.out.println("안녕하세요! 제 이름은 " + name + "이고, 나이는 " + age + "살 입니다.");
    }
}
package lesson03;

public class Ex02_Main {
    public static void main(String[] args) {
        Ex02_Dog dog1 = new Ex02_Dog();
        dog1.name = "토리";
        dog1.age = 2;
        dog1.introduce();
        dog1.bark();

        Ex02_Dog dog2 = new Ex02_Dog();
        dog2.name = "뽀야";
        dog2.age = 8;
        dog2.introduce();
        dog2.bark();
    }
}
안녕하세요! 제 이름은 토리이고, 나이는 2살 입니다.
토리가 멍멍 짖습니다.
안녕하세요! 제 이름은 뽀야이고, 나이는 8살 입니다.
뽀야가 멍멍 짖습니다.

객체(Object) vs 인스턴스(Instance)

✅ 객체(Object)
클래스에 의해 생성된 모든 것.
속성과 동작(메서드) 을 가진 구체적인 ‘무언가’입니다.
ex) 사람이라는 개념이 있고, 이름과 나이 등의 정보를 가진 실제 사람 하나하나가 객체입니다.

✅ 인스턴스(Instance)
특정 클래스(Class)로부터 생성된 객체.
클래스(설계도)를 이용해서 만들어진 실제 결과물.
모든 인스턴스는 객체지만, 모든 객체가 반드시 인스턴스는 아님.

🍪 비유로 이해하기

  • 클래스: 쿠키 틀
  • 인스턴스: 쿠키 틀로 찍어낸 쿠키 (특정 틀로 만든 쿠키)
  • 객체: 그냥 쿠키 전체 (틀로 만들었든 손으로 만들었든 쿠키는 쿠키)

2. 생성자(Constructor)

클래스로부터 객체를 생성할 때 호출되는 특수한 메서드.
객체가 생성될 때 필요한 초기값을 설정(초기화)해주는 것.

  • 이름 : 클래스 이름과 동일해야 함 (반드시!)
  • 반환형 : 없음 (void도 쓰지 않음)
  • 호출 시점 : new 키워드로 객체를 생성할 때 자동으로 호출됨
  • 여러 개 가능 : 매개변수를 달리하여 생성자 오버로딩 가능

매개변수가 없는 생성자

public class Person {
    String name;
    int age;

    // 기본 생성자
    public Person() {
        System.out.println("기본 생성자 호출됨!");
    }
}

매개변수가 있는 생성자

this: 현재 객체 자신을 가리킴
this(...): 다른 생성자 호출 (생성자 안에서만 첫 줄에 사용 가능)

package lesson03;

public class Ex03_Person {
    String name;
    int age;

    public Ex03_Person(String name, int age){
        this.name = name;
        this.age = age;
    }
}

class Ex03_Main {
    public static void main(String[] args) {
        Ex03_Person person = new Ex03_Person("김사과", 20);
        System.out.println(person.name + ", " + person.age);
    }
}

3. 생성자 오버로딩

같은 이름의 생성자를 매개변수 개수나 타입이 다르게 여러 개 정의할 수 있다.

package lesson03;

public class Ex04_User {
    String name;
    int age;

    public Ex04_User(){
        this("이름없음",0); // 생성자에서 또 다른 생성자를 호출할 때
        System.out.println("기본 생성자 호출됨");
    }

    public Ex04_User(String name){
        this(name, 0);
        System.out.println("이름만 받는 생성자 호출됨");
    }

    public Ex04_User(String name, int age){
        System.out.println("이름과 나이를 받는 생성자 호출됨");
        if(age < 0){
            System.out.println("나이는 음수가 될 수 없습니다.");
            this.age = 0;
        }else{
            this.age = age;
        }

        if(name == null || name.trim().isEmpty()){
            this.name = "이름없음";
        }else{
            this.name = name;
        }
    }

    public void introduce(){
        System.out.println("안녕하세요. 제 이름은 "+name+"이고, 나이는 "+age+"살 입니다.");
    }

    public static void main(String[] args) {
        Ex04_User u1 = new Ex04_User();
        Ex04_User u2 = new Ex04_User("김사과");
        Ex04_User u3 = new Ex04_User("반하나", 25);

        u1.introduce();
        u2.introduce();
        u3.introduce();
    }
}

3. null

참조형 변수(객체)의 기본값.
"아직 어떤 객체도 참조하지 않고 있음"을 의미한다.
null은 기본형(int, double 등)에는 사용할 수 없고, 객체 타입(참조형)에만 사용할 수 있다.

String s = null;  // s는 아직 아무 문자열도 참조하지 않음

1. NullPointerException(NPE)이란?

null 값을 가진 변수에서 메서드를 호출하거나 필드에 접근하려고 하면 자바는 NullPointerException을 발생시킨다.

String s = null;
System.out.println(s.length());  // ❌ NPE 발생

2. null 처리 시 주의할 점 5가지

메서드 호출 전에 null 체크 필수

if (s != null) {
    System.out.println(s.length());
}

equals 비교는 null 객체로 하지 말고, 상수로 시작

String name = null;

// 잘못된 방식 (null에서 메서드 호출)
if (name.equals("김사과")) { }  // ❌ NPE

// 올바른 방식
if ("김사과".equals(name)) { }  // ✅ 안전

래퍼 클래스는 언박싱 시 null이면 에러

Integer num = null;
int x = num;  // ❌ NPE 발생 (null → int 언박싱 불가)

// 해결 방법
if (num != null) {
    int x = num;
}
// 또는
int x = (num != null) ? num : 0;

배열 또는 리스트에서 null 요소 존재 여부 확인

String[] names = new String[3];  // [null, null, null]

for (String n : names) {
    if (n != null) {
        System.out.println(n.length());
    }
}

Optional (선택적) 사용으로 null 안전하게 처리

Optional<String> opt = Optional.ofNullable(name);

opt.ifPresent(n -> System.out.println(n.length())); // null이면 실행 안 함

String result = opt.orElse("기본값"); // null이면 기본값 사용

4. 가비지 컬렉터(Garbage Collector)

자바에서 더 이상 사용되지 않는 객체를 자동으로 메모리에서 제거해주는 기능.
객체가 생성되면 힙(heap) 메모리에 저장되는데, 더 이상 어떤 변수나 객체에서도 참조되지 않는 객체는 "쓸모없다"고 판단되어 가비지 컬렉터의 대상이 된다.

이 과정은 JVM이 자동으로 수행하며, 메모리 누수를 방지하고 안정적인 프로그램 실행을 돕는다.
System.gc()로 수동 요청도 가능하지만, 실제 실행 여부는 JVM의 판단에 따른다.

객체에 대한 참조(reference)가 사라지면, JVM은 "이건 이제 필요 없는 객체"라고 판단하고 제거 대상에 넣는다.

Dog dog = new Dog();  // Dog 객체 생성
dog = null;           // 참조 제거 → 이 객체는 더 이상 접근할 수 없음

1. 가비지 컬렉터의 동작시기

가비지 컬렉터는 JVM이 자동으로 판단하여 실행한다.

  • 메모리가 부족할 때
  • 시스템이 한가할 때
  • 명시적으로 요청할 수도 있다. (단, 반드시 실행된다는 보장은 없음)
System.gc();  // JVM에게 가비지 컬렉션을 요청함 (강제는 아님)

2. 가비지 컬렉터의 내부 동작 방법

  • Reachability 분석
    루트(root, 예: 지역변수, static 변수 등)에서부터 접근할 수 없는 객체를 탐지

  • Mark and Sweep (표시 & 제거)
    사용 중인 객체는 표시(mark)
    사용되지 않는 객체는 제거(sweep)

  • Compact (압축)
    남은 객체들을 메모리 앞쪽으로 정리해서 메모리 단편화 방지

단편화

메모리에 빈 공간이 조각조각 나뉘어 흩어져 있어서, 충분한 총 공간은 있지만 연속된 공간이 부족하여 새로운 데이터를 저장할 수 없는 상태.

자바의 가비지 컬렉터는 필요 시 남은 객체들을 앞으로 땡겨서(압축하여) 단편화를 줄이는 작업(compaction)도 수행한다.

5. 패키지(Package)

관련된 클래스, 인터페이스, 열거형 등을 논리적으로 묶어주는 디렉터리 형태의 구조.

코드의 조직화와 관리를 쉽게 해준다.
패키지를 사용하면 클래스 이름이 충돌하는 것을 방지할 수 있고, 서로 관련 있는 기능들을 그룹으로 묶어 모듈화와 재사용성을 높일 수 있다.

패키지는 package 키워드로 선언하며,
예를 들어 package com.example.util;처럼 계층적으로 구성할 수 있고, 다른 패키지의 클래스를 사용하려면 import 문을 통해 명시적으로 불러와야 한다.

1. 패키지 선언

자바 소스파일의 가장 첫 줄에 package 키워드를 사용한다.

src/
 └── com/
     └── example/
         └── utils/
             └── MathHelper.java
package com.example.utils;

public class MathHelper {
    public static int add(int a, int b) {
        return a + b;
    }
}

2. 다른 패키지 클래스 사용

import com.example.utils.MathHelper;

public class Main {
    public static void main(String[] args) {
        int result = MathHelper.add(5, 10);
        System.out.println("결과: " + result);
    }
}

전체 패키지를 임포트할 수도 있다.

import com.example.utils.*;

3. 기본 패키지 (default package)

패키지를 명시하지 않을 때 -> 기본 패키지 (default package)

profile
The light shines in the darkness.

0개의 댓글