🔌 SPARTA/Courses

객체지향 이해하기

eunjiom 2026. 1. 9. 21:11

✨ 클래스와 객체

 

1. 클래스

  • 객체를 만들 때 필요한 설계도
  • 첫 글자가 대문자

2. 객체

  • 실제로 존재하는 것
  • 객체 만들기
더보기
더보기
  • Person 클래스: 사람 객체를 만들기 위한 설계도
  • 객체를 만들때 new 라는 키워드를 사용
  • 인스턴스화: 객체를 만드는 과정
public class Person() { 
		...
}

 

3. 클래스 구조

 

1) 속성

  • 속성(특징)을 작성하는 곳
  • 속성들은 변수로 표현
더보기
더보기
  • 사람의 속성: 나이, 이름, 주소 등
  • 변수 선언
class Person {
		String name;
		int age;
		String address;
}
  • 객체 생성과 속성 접근
public class Main {

		public static void main(String[] args) {
		
        Person personA = new Person("eunji",27);
        Person personB = new Person("yutae",32); 
				
        System.out.println("설정전 personA 이름:"+personA.name);
        System.out.println("설정전 personB 이름:"+personB.name);
        personA.name = "eunji";
        personB.name ="yutae";
        System.out.println("설정후 personA 이름:"+personA.name);
        System.out.println("설정후 personB 이름:"+personB.name);
		}
}

2) 생성자(조립 설명서)

  • 클래스를 생성하면 기본 생성자는 자동으로 추가
더보기
더보기
public class Person {

		Person() {} // ✅ 기본생성자 자동추가, 하지만 보이지 않습니다.
}

class main

        Person personA = new Person();
        Person personB = new Person();
  • 생성자 특징

- 반환 자료형이 없음

- 클래스명과 이름이 똑음

- 여러 개가 존재할 수 있음

  • 생성자 정의
더보기
더보기

// 생성자 정의시 기본 생성자는 사라짐 > 기본 생성자 에러 발생

	class person
    Person(String name, int age){
        this.name = name;
        this.age = age;
        
   	class main
	Person personA = new Person("eunji",27);
	Person personB = new Person("yutae",32);
  • this: 객체 자신을 가리키는 키워드

3) 기능(메서드)

  • 더하기 기능
더보기
더보기
	calss person
	int plus(int value1, int value2){
	int result = value1 + value2;
	return result;
        
	calss main
	int result1 = personA.plus(2,7);
	int result2 = personB.plus(3,2);
	System.out.println("result1 ="+result1);
	System.out.println("result2 ="+result2);

4. 게터(gettter)

  • 클래스 속성을 가져오는 기능
더보기
더보기
	class person
    String getName(){
        return this.name;
        
   	class main
        String name = personA.getName();
        System.out.println("name ="+name);

5. 세터: 속성 설정 기능

  • 객체의 속성을 외부에서 설정할 수 있게 해주는 기능
더보기
더보기
class person
    void setAddress(String address){
        this.address = address;
        
class main
        personA.setAddress("서울");
        System.out.println("personA의 주소: "+personA.address);

 

✨ JVM 메모리 영역

 

1. 메모리 구조

2. Method Area

  • 클래스 정보 저장공간(도서관): 클래스 파일 내에 구조, 코드 등 있음
더보기
더보기
  • 프로그램이 실행되면 작성했던 모든 파일(.java)의 데이터가 Method(static)영역에 저장
  • 프로그램 실행 시점에 한번만 저장
  • Method 영역에 저장된 데이터는 프로그램 전체에서 공용으로 활용 가능
  • static 으로 선언된 변수와 메서드 저장

3. Heap Area

  • 객체가 생성되어 저장되는 공간(풍선비유)
더보기
더보기
  • new 키워드로 생성된 객체는 Heap 영역에 저장

3. StackArea

  • 메서드 실행 시 사용되는 공간(접시 쌓기): 지역변수, 호출정보 등
더보기
더보기
  • 메서드가 호출될 때마다 Stack 영역에 메모리가 할당
  • 특정 메서드 실행 > 해당 메서드의 정보와 변수가 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
    }
}

✨ 래퍼클래스

1. 래퍼클래스

  • 기본자료형 을 객체로 감싸는 클래스

1) 사용하는 이유

  • 객체 = 기능 제공
    기본형 = 속성, 기능 x
     > 속성, 기능을 가질 수 없는 기본형을 객체처럼 사용하기 위함
Integer num = 123; // 래퍼클래스
String str = num.toString(); // ✅ 편리한 기능

int a = 100; // 그냥 데이터 100
String str = a.toString(); // ❌ 변환 불가

 

2. 기본형

int a =1;
System.out.println("a ="+a);
a = 1 // run

 

3. 참조형

  • 참조형변수: 변수에 객체가 담김
  • 데이터가 저장된 heap 메모리 주소를 가리킴
  • ex) 객체, 배열 등
더보기
더보기
  • 객체
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()이 오버라이딩되어 있기 때문에 메모리 주소값이 나오지 않음

4. 직접 만들기

더보기
더보기
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
    }
}

5. 오토박싱 vs 언박싱

더보기
더보기
Integer num3 = 10; // 오토박싱 (기본형을 자동으로 래퍼 클래스 객체로 변환)
int num = num3;   // 오토 언박싱(참조형을 자동으로 기본형으로 변환)

1) 오토박싱

  • 기본형 → 래퍼형
  • Integer는 참조형(객체)이지만 기본형 int 값을 직접 대입
  • 컴파일러가 자동으로 Integer.valueOf(10)을 호출하여 객체를 생성
더보기
더보기
Integer num3 = 10; // ✅ 오토박싱

// ✅ 내부적 자동 처리(래퍼형 <- 기본형)
Integer num = Integer.valueOf(10);

✨ Static

1. 기능

  • 객체를 만들지 않고 클래스 이름만으로 사용 가능
  • 각 객체(인스턴스) 클래스영역에 저장된 데이터를 활용할 수 있음
더보기
더보기

 

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);

2. 인스턴스 멤버

 

1) 인스턴스 멤버

  • 객체를 만들때 마다 생성되는 변수와 메서드
  • 객체(인스턴스)를 생성한 후에만 사용

2) 인스턴스 변수

  • 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 객체의 데이터에 접근
    }
}

3) 인스턴스 메서드

  • 객체의 속성을 활용
더보기
더보기
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 객체의 메서드 실행
    }
}

3. 클래스 멤버

 

1) 클래스 멤버

  • 클래스 자체에 속하는 변수와 메서드
  • static 키워드를 사용해서 선언
  • 해당 클래스로 만들어진 객체가 공유해서 사용
  • 객체 생성 없이 사용 가능

2) 클래스 변수

  • 객체를 만들지 않아도 클래스명.변수명으로 접근가능
더보기
더보기
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);
    }
}

3) 클래스 메서드

  • 클래스 변수만 사용할 수 있고 인스턴스 변수는 사용할 수 없음
더보기
더보기
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
    }
}

4. 주의할 점

  • static 은 공유가 필요한 곳에 사용
  • Static 메서드에서는 인스턴스 변수에 접근 X
더보기
더보기
public class Person {
    String name;

    public static void staticMethod() {
        System.out.println(this.name);  // ⚠️ 오류 발생
    }
}
public class Example {
    int instanceVar = 10;

    public static void main(String[] args) {
        Example ex = new Example();
        System.out.println(ex.instanceVar);  // ✅ 정상 출력
    }
}
  • 프로그램 종료까지 메모리 저장됨 / 남용시 메모리 낭비

✨ final

1. 용도

  • 변수 변경x
  • 메서드에 선언시 오버라이딩x
  • 클래스 > 상속x

2. 상수

  • 변경X / 항상 일정한 값을 가짐
  • 대문자
  • static final 선언: 프로그램 실행 중 변경되면 안 됨
  • ex) PI(원주율)
  • static 없이 선언하면 각 객체를 가져 중복될 수 있음

3. 불변객체

 

1) 특징

  • 내부 상태 변경X
  • setter 없이 설계

2) 주의할 점

  • 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;
    }
}

 

3) 불변객체 값 변경 필요한 경우

  • 새로운 객체 생성 
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, 새 객체 생성
    }
}

✨ 인터페이스

1. 의미

  • 설계 표준 / 공통 규칙
  • 인터페이스 X / 일관되지 않음
더보기
더보기
class ACar {
    void move() {
        System.out.println("멋지게 이동합니다.");
    }
    
    void stop() {
		    System.out.println("멋지게 정지합니다.");
    }
}
class BCar {
    void drive() {
        System.out.println("빠르게 주행을 합니다.");
    }
}
public class Main {
    public static void main(String[] args) {
        ACar car1 = new LuxuryCar();
        BCar car2 = new SpeedCar();

				// ❌ 일관되지 않은 주행 명령어
        car1.move();  
        car1.stop();
        // ❌ 일관되지 않은 주행 명령어 + 멈출수 없음
        car2.drive(); 
    }
}
  • 인터페이스 적용 (implements 활용)
더보기
더보기
interface Car {
    void drive();
    void stop();
}
  • 규격 틀 제공
class ACar implements Car {

		@Override
    void drive() { // ✅ 인터페이스 규칙 준수
        System.out.println("멋지게 이동합니다."); // 구현 내용은 자유롭습니다.
    }
    
    @Override
    void stop() { // ✅ 인터페이스 규칙 준수
		    System.out.println("멋지게 정지합니다."); // 구현 내용은 자유롭습니다.
	  }
	  
	  void charge() { // 🎉 CarA 만의 기능을 확장 가능합니다.
			  System.out.println("차량을 충전합니다");
	  }
}
class BCar 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) {
        ACar car1 = new LuxuryCar();
        BCar car2 = new SpeedCar();

				// ✅ 각 차량의 공통 기능
        car1.drive();
        car1.stop();
        car2.drive();
        car2.stop();
        
        // ✅각 차량의 고유 기능(추가기능-인터페이스 확장)
        car1.charge();
        car2.autoParking();
    }
}

 

2. 인터페이스 다양한 기능

 

1) 다중구현

  • 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(); // "새가 착륙합니다."
    }
}

2) 다중상속

  • 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(); // "새가 착륙합니다."
    }
}

3. 인터페이스 안에 변수 선언

  • 변수 선언시 형식에 관계 없이 자동으로 상수로 선언
  • public static final 로 선언
  • 구현체 없이도 활용 가능
더보기
더보기
public interface Config {
    int POPULATION = 100; // public static final 로 선언됩니다.
}
public class Main {
    public static void main(String[] args) {
        System.out.println(Config.POPULATION);
    }
}

'🔌 SPARTA > Courses' 카테고리의 다른 글

자바 개념 확장  (0) 2026.01.15
객체지향 특징  (0) 2026.01.14
Java 기초문법(2)  (0) 2026.01.08
Java 기초문법(1)  (0) 2026.01.08
GIT  (0) 2026.01.06