실제 세계의 객체를 생각하면 된다 → 어떠한 상태(속성)를 갖고 특정 행위를 할 수 있는 독립적인 단위.
객체의 설계도, 속성과 동작을 정의한다.
사용자 정의 자료형(user defined data type)
상태(데이터)와 행동(메소드)를 함께 가지는 독립적인 단위
Class → Instantiate → Object
실제 메모리에 할당된 인스턴스
객체 중심의 프로그래밍 패러다임.
프로그램을 여러개의 객체로 구성된 시스템으로 바라보는 방식
장점
단점
장점
단점
데이터를 외부에서 직접 접근하지 못하게 하고, 메소드를 통해서만 접근할 수 있게 제한하는 개념.
데이터 + 메서드를 객체로 캡슐화하고, 외부에서는 객체 내부를 알 수 없도록 숨긴다.
파이썬의 캡슐화
완전히 기술적으로 막지는 않고, 관례로 구현된다. → 파이썬의 철학: “we are consenting adults here”
Protected: _ 클래스 및 하위 클래스에서 접근 가능.
class Person():
def __init__(self, name):
self._name = name
Private: __ (name mangling) 정의한 클래스 내에서만 접근 가능.
class Person():
def __init__(self, name):
self.__name = 0
@property
class User:
def __init__(self, age):
self._age = age
@property
def age(self):
print("getter 호출")
return self._age
@age.setter
def age(self, value):
print("setter 호출")
if value < 0:
raise ValueError("나이는 음수 불가")
self._age = value
u = User(20)
u.age # getter 호출
u.age = 30 # setter 호출
u.age ──> getter(age) ──> _age
u.age= ──> setter(age) ──> _age
접근 경로가 통제된다.
객체가 제공하는 행동(기능)만 드러내고, 내부 구현을 숨기는 설계 방식.
외부에서 객체의 내부 구현은 몰라도 된다. 객체 외부에서 메소드를 사용하는 사람은 구현 내용을 몰라도 사용할 수 있다.
기존에 작성된 클래스의 속성과 메소드를 물려받아 사용할 수 있다.
기존 코드를 재사용할 수 있다. 상속을 통해 다형성을 구현할 수 있다.
class Vehicle:
def __init__(self, name):
self.name=name
def move(self):
print(f"{self.name} 이동중")
class Car(Vehicle):
def __init__(self, name, wheels):
super().__init__(name)
self.wheels=wheels
def info(self):
print(f"{self.name} 바퀴는 {self.wheels}개")
def practice_inheritance():
banner("3) OOP: Inheritance")
car = Car("Taxi", 4)
car.move() # 예상: Taxi 이동 중
car.info() # 예상: Taxi 바퀴는 4개
하나의 메소드/클래스가 다양하게 동작할 수 있다.
오버라이딩(상속받은 메소드 재정의), 오버로딩(매개변수에 따라 여러개 정의)
# w/o polymorphism
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
return f"{self.name} says Woof!"
class Cat:
def __init__(self, name):
self.name = name
def meow(self):
return f"{self.name} says Meow!"
def make_animal_speak(animal):
if isinstance(animal, Dog):
print(animal.bark())
elif isinstance(animal, Cat):
print(animal.meow())
else:
raise ValueError("Unknown animal")
# with polymorphism
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
def make_animal_speak(animal):
print(animal.speak())
dog = Dog("Buddy")
cat = Cat("Whiskers")
make_animal_speak(dog)
make_animal_speak(cat)
같은 기능을 하는 메서드 이름을 같게 → 복잡성 줄이고, 코드 재사용, 기능 확장 용이