데이터 엔지니어링

패스트캠퍼스 환급챌린지 25일차: 데이터엔지니어링 초격차 강의 후기

Big Byte 2025. 4. 25. 23:43

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

 

자바 세상의 건축가 되기: 객체 지향 프로그래밍으로 설계하기! 🏗️

 

안녕하세요! 자바 마스터를 향한 여정에 다시 합류하신 여러분, 대환영입니다! 🎉

 

지난 시간에는 마법의 재봉틀 같은 반복문으로 지루한 작업을 자동화하는 법을 배웠죠! 코드가 훨씬 간결하고 강력해지는 것을 느끼셨을 거예요. 👍 연산자로 데이터를 요리하고, 조건문으로 길을 찾고, 반복문으로 작업을 자동화하는 능력까지 갖추셨으니, 이제 꽤나 복잡한 로직도 구현할 수 있게 되셨습니다!

 

하지만 프로그램이 점점 더 커지고 복잡해진다면 어떨까요? 예를 들어, 자동차 게임을 만든다고 상상해 보세요. 자동차의 색상, 속도, 연료 상태를 관리하고, 시동 걸기, 가속하기, 멈추기 같은 동작들을 구현해야겠죠. 지금까지 배운 것만으로는 이런 다양한 속성과 기능을 체계적으로 관리하기가 조금 벅찰 수 있어요. 🤯

 

코드가 뒤죽박죽 섞여서 어디서부터 손대야 할지 막막해질지도 모릅니다. 마치 레고 블록 없이 찰흙으로만 거대한 성을 만들려는 것과 같죠. 무너지기 쉽고, 수정하기도 어렵고요.

 

바로 이때, 세상을 더 체계적이고 효율적으로 모델링하는 새로운 프로그래밍 방식, **객체 지향 프로그래밍(Object-Oriented Programming, OOP)**이 우리의 구원투수로 등판합니다! 🌟 OOP는 마치 잘 설계된 레고 블록 세트처럼, 현실 세계의 개념들을 '객체'라는 단위로 만들어 조립해 나가는 방식이에요.

 

자, 이제부터 코드를 단순히 나열하는 것을 넘어, 세상을 모델링하고 조립하는 '설계자'가 되어볼까요? 객체 지향의 세계로 함께 떠나봅시다! 🔥

1. 객체 지향 프로그래밍(OOP)이란 무엇일까요? 🤔 (What is OOP?)

OOP는 단순히 코드를 짜는 기술을 넘어, 프로그램을 바라보는 '관점'의 변화예요. 이전까지 우리가 배운 것처럼 절차(순서)에 따라 코드를 실행하는 방식(절차 지향 프로그래밍)에서 벗어나, 현실 세계처럼 상호작용하는 '객체'들의 집합으로 프로그램을 구성하는 거죠.

 

우리가 사는 세상은 다양한 '객체'(사람, 자동차, 강아지, 컴퓨터 등)로 이루어져 있고, 각 객체는 자신만의 '속성'(이름, 색상, 속도 등)과 '행동'(말하기, 움직이기, 짖기, 계산하기 등)을 가지고 있잖아요? OOP는 바로 이 개념을 프로그래밍에 그대로 가져온 거예요!

OOP를 사용하면 다음과 같은 장점들이 있어요:

  • 코드 재사용성 증가: 잘 만들어진 '객체'(레고 블록)는 다른 프로그램에서도 쉽게 가져다 쓸 수 있어요. ♻️
  • 유지보수 용이성: 문제가 생긴 객체만 찾아서 수정하면 되니, 전체 코드를 뒤지지 않아도 돼요. 🔧
  • 복잡한 문제 해결 능력 향상: 큰 문제를 작은 객체 단위로 나누어 생각할 수 있어, 더 체계적으로 접근할 수 있어요. 🧩
  • 현실 세계 모델링: 실제 세상의 개념을 코드로 표현하기 좋아, 프로그램을 더 직관적으로 이해하고 설계할 수 있어요. 🌍

 

2. 클래스 (Class): 객체의 청사진! 📜📐

 

객체 지향 프로그래밍의 첫걸음은 바로 클래스(Class)를 이해하는 것입니다. 클래스는 객체를 만들기 위한 '설계도' 또는 '틀(template)'이라고 생각하면 쉬워요.

예를 들어 '붕어빵 틀' 🍞을 생각해 봅시다. 이 틀은 붕어빵이 어떤 모양(🐟)을 가질지, 어떤 재료(팥, 슈크림?)를 넣을 수 있는지 등을 정의하죠. 하지만 붕어빵 틀 자체가 붕어빵은 아니에요. 틀은 붕어빵을 만들기 위한 '규격'일 뿐이죠.

자바에서 클래스는 객체가 가지게 될 '상태(State)'와 '행동(Behavior)'을 정의합니다.

  • 상태 (State): 객체가 가질 데이터, 속성. 멤버 변수(Member Variable) 또는 필드(Field)라고 불러요. (예: 자동차의 색상, 현재 속도)
  • 행동 (Behavior): 객체가 할 수 있는 동작, 기능. 메소드(Method)라고 불러요. (예: 자동차의 시동걸기(), 가속하기())

자, 간단한 Car 클래스를 설계해 볼까요?

 

      public class Car {
    // 상태 (Fields / 멤버 변수)
    String color; // 자동차의 색상
    int speed;    // 자동차의 현재 속도
    boolean isEngineOn; // 엔진 시동 상태

    // 행동 (Methods / 메소드)
    void startEngine() { // 시동을 거는 행동
        if (!isEngineOn) {
            isEngineOn = true;
            System.out.println("부릉부릉~ 시동이 걸렸습니다! 🔥");
        } else {
            System.out.println("이미 시동이 걸려있어요.");
        }
    }

    void accelerate() { // 가속하는 행동
        if (isEngineOn) {
            speed += 10; // 속도를 10 증가
            System.out.println("슝~! 속도가 " + speed + "km/h로 증가했습니다! 💨");
        } else {
            System.out.println("시동부터 걸어주세요!");
        }
    }

    void stop() { // 멈추는 행동
        if (speed > 0) {
            speed = 0;
            System.out.println("끼이익! 자동차가 멈췄습니다. 🛑");
        }
    }
}

이렇게 Car라는 클래스(설계도)를 정의했어요. 이 설계도에는 자동차가 가질 수 있는 속성(색상, 속도, 엔진 상태)과 할 수 있는 행동(시동 걸기, 가속, 정지)이 명시되어 있죠. 하지만 아직 실제 자동차가 만들어진 것은 아니에요!

3. 객체 (Object): 살아 숨 쉬는 실체! 🚗💨

클래스라는 '설계도'가 준비되었으니, 이제 실제 '제품'을 만들어 볼 차례입니다! 클래스로부터 만들어진 실제 메모리 공간을 차지하는 실체를 바로 객체(Object) 또는 인스턴스(Instance)라고 불러요.

'붕어빵 틀(클래스)'로 실제 '붕어빵(객체)'을 찍어내는 것과 같아요! 🍞➡️🐟

하나의 클래스(틀)로 여러 개의 객체(붕어빵)를 만들 수 있고, 각 객체는 자신만의 독립적인 상태(예: 다른 색상, 다른 속도)를 가질 수 있어요.

객체를 만드는 과정을 '인스턴스화(Instantiation)'라고 하며, 자바에서는 new 키워드를 사용합니다.

      public class Main {
    public static void main(String[] args) {
        // Car 클래스(설계도)를 이용해 실제 Car 객체(실체)를 만듭니다!
        Car myCar = new Car();   // 'new Car()'를 통해 Car 객체 생성! myCar는 이 객체를 가리킴.
        Car yourCar = new Car(); // 또 다른 Car 객체 생성! yourCar는 다른 객체를 가리킴.

        // 각 객체는 독립적인 상태(멤버 변수)를 가집니다.
        myCar.color = "빨간색"; // myCar 객체의 color 설정
        myCar.speed = 0;
        myCar.isEngineOn = false;

        yourCar.color = "파란색"; // yourCar 객체의 color 설정
        yourCar.speed = 20;
        yourCar.isEngineOn = true;

        System.out.println("내 차 정보:");
        System.out.println("- 색상: " + myCar.color); // 출력: 빨간색
        System.out.println("- 속도: " + myCar.speed);   // 출력: 0
        myCar.startEngine(); // myCar 객체의 메소드 호출 (시동이 걸릴 것)
        myCar.accelerate();  // myCar 객체의 메소드 호출 (속도 증가)

        System.out.println("\n네 차 정보:");
        System.out.println("- 색상: " + yourCar.color); // 출력: 파란색
        System.out.println("- 속도: " + yourCar.speed);   // 출력: 20
        yourCar.startEngine(); // yourCar 객체의 메소드 호출 (이미 시동 걸려있음)
        yourCar.accelerate();  // yourCar 객체의 메소드 호출 (속도 증가)

        // myCar의 상태 변경이 yourCar에 영향을 주지 않아요!
        System.out.println("\n다시 내 차 속도: " + myCar.speed); // 출력: 10
        System.out.println("다시 네 차 속도: " + yourCar.speed); // 출력: 30
    }
}
    

어때요? myCaryourCar는 같은 Car 클래스로 만들었지만, 각각 다른 색상과 속도, 엔진 상태를 가진 별개의 존재가 되었죠? 이것이 바로 객체의 매력입니다! ✨

4. 생성자 (Constructor): 객체의 탄생 비법! ✨👶

객체가 new 키워드를 통해 세상에 태어나는 순간! ✨👶 그냥 뿅 하고 나타나는 게 아니라, 특별한 '초기화(Initialization)' 과정을 거치게 됩니다. 이 객체 탄생의 순간에 호출되어 객체의 초기 설정을 담당하는 아주 특별한 메소드가 바로 생성자(Constructor)입니다.

마치 아기가 태어날 때 이름(초기 상태)을 지어주는 것과 비슷하다고 할까요? 혹은 자동차 공장에서 막 출고된 자동차의 기본 설정(색상, 초기 연료량 등)을 세팅하는 역할과 같죠! 🏭

생성자는 다음과 같은 특징을 가집니다:

  1. 이름이 클래스 이름과 동일해야 합니다.
  2. 리턴 타입(void, int 등)을 명시하지 않습니다. (메소드와의 차이점!)

우리가 클래스를 만들 때 생성자를 직접 정의하지 않으면, 자바 컴파일러가 기본 생성자(Default Constructor)라는 것을 자동으로 만들어줍니다. 기본 생성자는 아무런 코드도 없고, 매개변수도 없는 텅 빈 생성자예요 (public Car() {} 와 같은 형태).

하지만 우리가 객체가 생성될 때 특정 초기값을 가지도록 하고 싶다면, 직접 생성자를 만들 수 있습니다! 이걸 매개변수가 있는 생성자라고 불러요.

Car 클래스에 생성자를 추가해 볼까요? 자동차가 만들어질 때 색상을 바로 지정할 수 있도록요!

      public class Car {
    String color;
    int speed;
    boolean isEngineOn;

    // 매개변수가 있는 생성자 ✨
    public Car(String initialColor) {
        System.out.println(initialColor + " 색상의 자동차가 공장에서 막 출고되었습니다! 🎉");
        color = initialColor; // 전달받은 색상으로 멤버 변수(color)를 초기화
        speed = 0;            // 속도는 0으로 초기화
        isEngineOn = false;     // 시동은 꺼진 상태로 초기화
    }

    // 기본 생성자 (이제 직접 만들어줘야 함!)
    // 매개변수 있는 생성자를 하나라도 만들면, 컴파일러는 기본 생성자를 자동으로 만들어주지 않아요.
    // 만약 'new Car()' 형태로도 객체를 생성하고 싶다면, 이렇게 직접 추가해야 합니다.
    public Car() {
        System.out.println("기본 색상(미정) 자동차가 출고되었습니다.");
        color = "미정";
        speed = 0;
        isEngineOn = false;
    }


    // 행동 (메소드들... startEngine, accelerate, stop 등은 이전과 동일)
    void startEngine() { /* ... */ }
    void accelerate() { /* ... */ }
    void stop() { /* ... */ }
}

// 생성자를 사용하는 방법
public class Main {
    public static void main(String[] args) {
        // 생성자 호출! 객체 생성 시 괄호 안에 값을 넣어줍니다.
        Car redCar = new Car("빨간색"); // 매개변수 있는 생성자 호출! redCar는 '빨간색'으로 초기화됨
        Car blueCar = new Car("파란색"); // blueCar는 '파란색'으로 초기화됨
        Car defaultCar = new Car();    // 기본 생성자 호출!

        System.out.println("첫 번째 차 색상: " + redCar.color);   // 출력: 빨간색
        System.out.println("두 번째 차 색상: " + blueCar.color);  // 출력: 파란색
        System.out.println("세 번째 차 색상: " + defaultCar.color); // 출력: 미정
    }
}
    

이제 new Car("빨간색")처럼 객체를 생성하는 동시에 초기 색상을 지정할 수 있게 되었어요! 생성자는 객체가 처음부터 유효한 상태를 갖도록 보장해주는 아주 중요한 역할을 한답니다! 👍

 

5. 정리하며 📝

와~ 오늘은 자바 프로그래밍의 핵심 패러다임인 객체 지향 프로그래밍의 기초를 튼튼히 다졌습니다! 🏛️✨ 이제 여러분은 단순한 코드 작성자를 넘어, 프로그램을 '설계'하는 건축가에 한 발짝 더 다가섰어요!

오늘 배운 핵심 개념들을 다시 한번 되짚어 볼까요?

  • 객체 지향 프로그래밍 (OOP): 현실 세계를 '객체' 단위로 모델링하여 코드를 구성하는 방식! (재사용성 UP! 유지보수 UP!) 🌟
  • 클래스 (Class): 객체를 만들기 위한 청사진 또는 . 객체의 상태(멤버 변수)와 행동(메소드)을 정의. 📜📐
  • 객체 (Object): 클래스로부터 new 키워드를 통해 만들어진 실제 메모리 상의 인스턴스. 고유한 상태를 가짐. 🚗💨
  • 생성자 (Constructor): 객체가 생성될 때 단 한 번 호출되어 초기화를 담당하는 특별한 메소드. (클래스 이름과 동일, 리턴 타입 없음) ✨👶

이제 여러분은 코드를 '부품(객체)' 단위로 생각하고 조립하는 방법을 알게 되었어요! 이 개념들은 앞으로 자바를 더 깊이 배우면서 상속, 다형성 등 더 흥미로운 주제로 확장될 거예요. 오늘 배운 클래스, 객체, 생성자 개념은 그 모든 것의 기초가 되니, 꼭! 직접 코드로 만들어보면서 '내 것'으로 만드시길 바랍니다! 💪 자동차 클래스도 직접 만들어보고, Dog 클래스나 Person 클래스처럼 다른 개념들도 클래스로 한번 설계해보세요!


아, 그리고 벌써 금요일이네요! 한 주 동안 열심히 달려오신 여러분, 정말 수고 많으셨습니다! 😄 내일부터는 신나는 주말이니, 오늘 배운 내용 가볍게 복습하시고, 머리도 식히면서 즐거운 주말 보내시길 바라요! 🥳 저는 다음 시간에 더 유익하고 재미있는 자바 이야기로 돌아오겠습니다! 그때까지 모두들 해피 코딩 & 해피 주말! 🔥👋

 

https://abit.ly/lisbva