와우! 루비 여정의 절반 가까이 다가오고 있습니다! 🚀 지난 Part 5: 코드 재사용 끝판왕, 메소드 만들기에서는 코드를 깔끔하게 정리하고 재사용하는 마법, 메소드를 배웠습니다. 이제 루비의 핵심 철학이자 강력함의 근원이라 할 수 있는 객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 세계로 첫발을 내디딜 시간입니다!
OOP라는 용어가 조금 어렵게 느껴질 수 있지만, 걱정 마세요! 😊 OOP는 우리가 현실 세계를 이해하는 방식과 매우 유사해서, 개념만 잘 잡으면 오히려 코드를 더 직관적이고 체계적으로 만들 수 있게 도와줍니다. 이번 파트에서는 OOP의 가장 기본이 되는 두 가지 개념, 바로 객체를 만드는 설계도인 클래스(Class)와 그 설계도로 만들어진 실제 사물인 객체(Object)에 대해 쉽고 재미있게 알아볼 거예요.
준비되셨나요? 루비가 왜 객체 지향 언어인지, 그 매력을 함께 느껴봅시다!
🤔 객체 지향 프로그래밍(OOP)이란 무엇일까요?
복잡하게 생각할 필요 없어요! 객체 지향 프로그래밍은 우리가 세상을 바라보는 방식처럼, 프로그램을 여러 개의 독립적인 객체(Object)들의 상호작용으로 보는 관점입니다.
여기서 객체란 무엇일까요? 우리 주변의 모든 것, 예를 들어 '강아지', '자동차', '스마트폰' 등을 생각해 보세요. 이들은 각각 고유한 특징(상태, State)과 할 수 있는 행동(행동, Behavior)을 가지고 있습니다.
- 강아지 🐶:
- 상태: 이름, 품종, 색깔, 나이 등
- 행동: 짖다, 꼬리 흔들다, 먹다, 자다 등
- 자동차 🚗:
- 상태: 색깔, 모델명, 현재 속도, 연료량 등
- 행동: 시동 걸다, 가속하다, 멈추다, 경적 울리다 등
OOP는 바로 이런 현실 세계의 개념을 프로그래밍에 도입한 것입니다! 관련된 데이터(상태)와 그 데이터를 처리하는 함수(행동, 메소드)를 하나로 묶어 '객체'로 만들고, 이 객체들이 서로 메시지를 주고받으며 프로그램이 동작하게 만드는 방식이죠.
💡 루비는 모든 것이 객체!
놀랍게도 루비에서는 우리가 지금까지 배웠던 숫자(10
), 문자열("hello"
), 배열([]
), 심지어true
,false
,nil
까지도 모두 객체랍니다! 그래서 각 데이터 타입별로 다양한 메소드(.length
,.class
,.to_i
등)를 사용할 수 있었던 거예요. 😉
📜 객체의 설계도: 클래스 (Class)
세상에 수많은 강아지가 있지만, '강아지'라는 공통된 특징과 행동을 가지고 있죠? OOP에서는 이렇게 동일한 종류의 객체들이 가져야 할 공통적인 상태와 행동을 정의해 놓은 '틀' 또는 '설계도'를 클래스(Class)라고 부릅니다.
붕어빵 틀이 있으면 똑같은 모양의 붕어빵을 여러 개 만들 수 있듯이, 클래스를 정의해두면 그 클래스에 맞는 객체들을 쉽게 만들어낼 수 있습니다.
루비에서 클래스를 정의하는 방법은 `class` 키워드를 사용하고, 클래스 이름을 정한 뒤 `end`로 마무리합니다.
클래스 이름은 반드시 대문자로 시작하는CamelCase
(캐멀 케이스) 표기법
을 사용해야 합니다!
# 'Dog' 라는 이름의 클래스를 정의합니다. (아직 내용은 비어있음)
class Dog
# 여기에 강아지 객체가 가져야 할 상태와 행동을 정의할 거예요.
end
이렇게 클래스를 정의하는 것만으로는 아직 아무 일도 일어나지 않아요. 설계도만 만들어 놓은 상태니까요!
🐶 설계도로 실제 강아지 만들기: 객체 (Object/Instance) 생성
이제 설계도(클래스)를 사용해서 실제 강아지(객체)를 만들어 봅시다! 클래스로부터 만들어진 실제 객체를 특별히 **인스턴스(Instance)**라고 부르기도 합니다.
객체(인스턴스)를 만드는 방법은 클래스 이름 뒤에 .new
메소드를 호출하는 것입니다.
# Dog 클래스 설계도를 사용하여 실제 강아지 객체(인스턴스)를 만듭니다.
dog1 = Dog.new
dog2 = Dog.new
puts dog1 # 출력: # (고유한 ID를 가진 Dog 객체가 생성됨)
puts dog2 # 출력: # (dog1과는 다른 ID를 가진 객체)
# dog1과 dog2는 같은 Dog 클래스로 만들었지만, 서로 다른 별개의 객체입니다!
puts dog1 == dog2 # 출력: false
Dog.new
를 호출할 때마다 메모리 상에 새로운 Dog 객체가 만들어집니다. 마치 붕어빵 틀로 붕어빵을 계속 찍어내는 것과 같아요!
🏷️ 객체의 상태 저장: 인스턴스 변수 (Instance Variables)
각각의 강아지 객체는 자신만의 이름, 품종 등의 상태 정보를 가져야겠죠? 이렇게 각 객체(인스턴스)가 **개별적으로 가지는 상태(데이터)**를 저장하는 변수를 인스턴스 변수(Instance Variable)라고 합니다.
인스턴스 변수는 클래스 정의 내부에서 사용하며, 이름 앞에 골뱅이 기호(@
)를 붙여서 구분합니다. (예: @name
, @breed
)
class Dog
# 아직 인스턴스 변수를 어떻게 설정할지는 정의하지 않았어요!
# 잠시 후 initialize 메소드에서 설정하는 법을 배웁니다.
end
중요한 점은, 인스턴스 변수는 **각 객체별로 독립적으로 존재**한다는 것입니다. dog1
객체의 @name
과 dog2
객체의 @name
은 서로 다른 값을 가질 수 있습니다.
🐾 객체의 행동 정의: 인스턴스 메소드 (Instance Methods)
객체는 상태(데이터)뿐만 아니라 행동(기능)도 가져야 한다고 했죠? 객체가 할 수 있는 행동을 정의하는 것이 바로 인스턴스 메소드(Instance Method)입니다.
인스턴스 메소드는 클래스 정의 내부에 `def ... end` 를 사용하여 정의합니다. 우리가 Part 5에서 배운 일반적인 메소드 정의 방법과 동일해요!
인스턴스 메소드 안에서는 @
기호를 사용하여 해당 객체의 인스턴스 변수에 접근할 수 있습니다.
class Dog
# 이 메소드는 아직 @name 변수를 설정하는 부분이 없어서 제대로 동작하지 않아요.
# 아래 initialize 예제에서 완성됩니다!
def bark
# 가정: @name 이라는 인스턴스 변수에 강아지 이름이 저장되어 있다고 생각하고...
puts "#{@name}가(이) 멍멍! 짖습니다." # @name으로 해당 객체의 이름에 접근
end
end
# dog1 객체를 만들고 bark 메소드를 호출해봅시다.
dog1 = Dog.new
# dog1.bark # 아직 @name이 없어서 오류가 날 수 있어요! (또는 nil 출력)
bark
메소드는 Dog 클래스로 만들어진 객체(인스턴스)만 사용할 수 있는 '행동'입니다.
✨ 객체 탄생의 순간: `initialize` 메소드
객체를 처음 만들 때(`new` 호출 시) 이름이나 품종 같은 초기 상태를 설정해주고 싶을 거예요. 이때 사용하는 것이 바로 `initialize` 라는 특별한 메소드입니다!
initialize
메소드는 클래스 내부에 `def initialize ... end` 로 정의하며, .new
메소드가 호출될 때 자동으로 실행됩니다. 주로 객체의 인스턴스 변수들을 초기화하는 역할을 합니다.
initialize
메소드도 일반 메소드처럼 매개변수를 받을 수 있습니다. .new
를 호출할 때 전달하는 인자들이 이 `initialize` 메소드의 매개변수로 전달됩니다!
class Dog
# 객체가 생성될 때 이름(name)과 품종(breed)을 받아서 인스턴스 변수에 저장
def initialize(name, breed)
@name = name # 매개변수로 받은 name 값을 @name 인스턴스 변수에 저장
@breed = breed # 매개변수로 받은 breed 값을 @breed 인스턴스 변수에 저장
puts "#{name}(#{breed}) 강아지가 태어났어요! 🥳"
end
# 이제 @name 인스턴스 변수가 있으니 제대로 동작!
def bark
puts "#{@name}가(이) 멍멍! 짖습니다. 🐕"
end
# 강아지 정보 출력 메소드 추가
def display_info
puts "이름: #{@name}, 품종: #{@breed}"
end
end
# .new 를 호출하면서 initialize 메소드에 필요한 인자들을 전달!
dog1 = Dog.new("보리", "시바견") # name="보리", breed="시바견" 전달
dog2 = Dog.new("뭉치", "말티즈") # name="뭉치", breed="말티즈" 전달
puts "--- 강아지 정보 ---"
dog1.display_info # 출력: 이름: 보리, 품종: 시바견
dog2.display_info # 출력: 이름: 뭉치, 품종: 말티즈
puts "\n--- 강아지 행동 ---"
dog1.bark # 출력: 보리가(이) 멍멍! 짖습니다. 🐕
dog2.bark # 출력: 뭉치가(이) 멍멍! 짖습니다. 🐕
이제 Dog.new
를 통해 강아지 객체를 만들 때 이름과 품종을 지정해주면, 각 강아지 객체는 자신만의 이름(@name
)과 품종(@breed
) 상태를 가지고 태어나게 됩니다! 그리고 bark
나 display_info
같은 행동(메소드)을 수행할 수 있죠.
🎮 오늘의 실습: '고양이' 클래스 만들기!
이번에는 여러분이 직접 '고양이' 클래스를 만들어 봅시다!
요구사항:
- `Cat` 이라는 이름의 클래스를 정의합니다.
- `initialize` 메소드를 정의하여, 고양이 객체가 생성될 때 이름(
name
)을 인자로 받아@name
인스턴스 변수에 저장하도록 합니다. 생성 시 "야옹! #{이름} 고양이가 나타났습니다." 메시지 출력. - `meow` 라는 인스턴스 메소드를 정의하여, 호출 시 "#{이름}가(이) 야옹~ 하고 웁니다. 🐈" 메시지를 출력하도록 합니다.
- `Cat.new`를 사용하여 이름이 "나비"인 고양이 객체와 이름이 "치즈"인 고양이 객체를 각각 만듭니다.
- 만든 두 고양이 객체의 `meow` 메소드를 각각 호출하여 잘 작동하는지 확인합니다.
👇 아래는 정답 코드 예시입니다. 꼭 먼저 스스로 만들어보세요!
# 1. Cat 클래스 정의
class Cat
# 2. initialize 메소드 정의 (이름 받아서 저장 및 메시지 출력)
def initialize(name)
@name = name
puts "야옹! #{@name} 고양이가 나타났습니다. 😼"
end
# 3. meow 메소드 정의
def meow
puts "#{@name}가(이) 야옹~ 하고 웁니다. 🐈"
end
end
# 4. 고양이 객체 생성
cat1 = Cat.new("나비")
cat2 = Cat.new("치즈")
puts "\n--- 고양이 울음소리 ---"
# 5. meow 메소드 호출 확인
cat1.meow
cat2.meow
💡 Part 6 핵심 요약
- 객체 지향 프로그래밍 (OOP): 현실 세계처럼 프로그램을 상태와 행동을 가진 독립적인 객체들의 상호작용으로 모델링하는 방식.
- 클래스 (Class): 객체를 만들기 위한 설계도 또는 틀.
class 이름 ... end
(이름은 대문자 CamelCase).- 객체 (Object/Instance): 클래스 설계도로 만들어진 실제 사물.
클래스명.new
로 생성. 각 객체는 고유함.- 인스턴스 변수 (Instance Variable): 각 객체가 독립적으로 가지는 상태(데이터). 클래스 내에서
@변수명
으로 사용.- 인스턴스 메소드 (Instance Method): 객체가 할 수 있는 행동(기능). 클래스 내에서
def 메소드명 ... end
로 정의. 인스턴스 변수(@
) 접근 가능.initialize
메소드: 객체 생성 시(.new
호출 시) 자동으로 실행되는 초기화 메소드. 주로 인스턴스 변수 설정에 사용.
🚀 다음 단계로!
짝짝짝! 드디어 루비의 핵심인 객체 지향 프로그래밍의 첫 문을 열었습니다! 🎉 클래스와 객체의 기본 개념을 이해하고 직접 만들어보기까지 하셨네요. OOP는 처음에는 조금 낯설 수 있지만, 익숙해지면 코드를 훨씬 더 체계적이고 유연하게 관리할 수 있게 해주는 강력한 패러다임입니다.
오늘 배운 내용을 바탕으로 다양한 종류의 클래스(예: 자동차, 학생, 책 등)를 직접 만들어보고 객체를 생성하며 연습해보세요!
다음 Part 7: 객체 지향 레벨 업! (상속, 모듈, 믹스인) 에서는 객체 지향의 강력함을 더욱 깊이 느낄 수 있는 상속, 모듈, 그리고 루비의 특별한 기능인 믹스인(Mixin)에 대해 배울 예정입니다. 코드를 더욱 효율적으로 재사용하고 확장하는 방법을 기대해주세요! 😉
루비 #ruby #객체지향 #oop #클래스 #객체 #인스턴스 #initialize #인스턴스변수 #인스턴스메소드 #프로그래밍기초
'루비' 카테고리의 다른 글
🪄 루비(Ruby)의 숨겨진 보석: 블록, Proc, 람다 파헤치기! (Part 8) (0) | 2025.03.30 |
---|---|
🧬 루비(Ruby) 객체 지향 레벨 업: 상속, 모듈, 믹스인 마스터! (Part 7) (0) | 2025.03.30 |
🧩 루비(Ruby) 메소드 완전 정복: 코드 재사용의 마법! (Part 5) (0) | 2025.03.29 |
🗂️ 루비(Ruby) 데이터 정리의 기술: 배열과 해시 완전 정복! (Part 4) (2) | 2025.03.29 |
🧭 루비(Ruby) 코드 흐름 제어 마스터: 조건문과 반복문! (Part 3) (0) | 2025.03.29 |