1. 상속
기존 클래스의 속성과 메서드를 새로운 클래스가 물려받아서 사용하는 것을 의미한다.
1.1 기본 상속
하나의 클래스(부모 OR 슈퍼 클래스)의 속성과 메서드를 다른 클래스가 상속 받는다.
1.1.1 기본 상속 방법
기본 상속을 받기 위해서는 클래스 정의 시 부모 클래스의 이름을 괄호 안에 명시한다.
class Parent: # 부모 클래스
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, my name is {self.name}.")
# Child 클래스가 Parent 클래스를 상속받음
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # 부모 클래스의 __init__ 호출
self.age = age
def introduce(self):
print(f"I am {self.name} and I am {self.age} years old.")
# Child 클래스의 인스턴스 생성
child = Child("Alice", 30)
# Parent 클래스의 메서드 호출
child.greet() # 출력: Hello, my name is Alice.
# Child 클래스의 메서드 호출
child.introduce() # 출력: I am Alice and I am 30 years old.
1.2 다중 상속
하나의 클래스가 두 개 이상의 부모 클래스를 상속받는 것을 말한다.
1.2.1 다중 상속 방법
부모 클래스 이름을 괄호 안에 쉼표로 구분하여 명시한다.
class Parent1:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, my name is {self.name} from Parent1.")
class Parent2:
def __init__(self, age):
self.age = age
def introduce(self):
print(f"I am {self.age} years old from Parent2.")
# Child 클래스가 Parent1와 Parent2 클래스를 다중 상속받음
class Child(Parent1, Parent2):
def __init__(self, name, age):
Parent1.__init__(self, name)
Parent2.__init__(self, age)
def full_introduction(self):
self.greet()
self.introduce()
# Child 클래스의 인스턴스 생성
child = Child("Alice", 30)
# 두 부모 클래스의 메서드 호출
child.greet() # 출력: Hello, my name is Alice from Parent1.
child.introduce() # 출력: I am 30 years old from Parent2.
# Child 클래스의 메서드 호출
child.full_introduction()
# 출력:
# Hello, my name is Alice from Parent1.
# I am 30 years old from Parent2.
2. 다형성
동일한 이름의 메서드나 연산자가 다양한 방식으로 동작하는 것을 의미한다.
2.1 메서드 오버라이딩
자식 클래스에서 부모 클래스의 메서드를 재정의하는 것을 의미한다.
자식 클래스는 부모 클래스와 동일한 이름, 인자, 반환 타입을
가지는 메서드를 제공하여 특정 동작을 변경하거나 확장할 수 있다.
class Animal:
def make_sound(self):
print("Some generic sound")
class Dog(Animal):
def make_sound(self):
print("Bark")
class Cat(Animal):
def make_sound(self):
print("Meow")
# Animal 클래스는 make_sound를 정의하는데
# Dog 클래스와 Cat 클래스는 Animal 클래스를 상속받아서 재정의 한다.
2.2 인터페이스
클래스가 특정 메서드들을 반드시 구현하도록 강제한다.
추상 클래스를 사용하여 비슷한 기능을 구현 가능
from abc import ABC, abstractmethod
class Animal(ABC): # 추상 클래스
@abstractmethod
def make_sound(self): # 추상 메서드 ( 하위 클래스는 반드시 make_sound를 구현해야 한다.)
pass
class Dog(Animal):
def make_sound(self):
print("Bark")
class Cat(Animal):
def make_sound(self):
print("Meow")
3. 캡슐화와 정보 은닉
캡슐화는 데이터를 외부로부터 숨기고 보호하는 것을 의미한다.
3.1 접근 제어자
속성과 메서드에 대한 접근 권한을 제어한다.
3.1.1 Public
모든 클래스와 모듈에서 접근 가능.
class MyClass:
def __init__(self, value):
self.value = value # Public 속성
def display(self):
print(f"Value: {self.value}") # Public 메서드
# 객체 생성
obj = MyClass(10)
# Public 속성 접근
print(obj.value) # 출력: 10
# Public 메서드 호출
obj.display() # 출력: Value: 10
3.1.2 Protected
클래스 내부와 자식 클래스에서만 접근 가능. 이름 앞에 밑줄 하나(_)를 붙여 표시.
class MyClass:
def __init__(self, value):
self._value = value # Protected 속성
def _display(self):
print(f"Value: {self._value}") # Protected 메서드
class SubClass(MyClass):
def show(self):
print(f"SubClass Value: {self._value}") # 자식 클래스에서 접근 가능
# 객체 생성
obj = SubClass(10)
# Protected 속성 접근 (가능하지만 권장하지 않음)
print(obj._value) # 출력: 10
# Protected 메서드 호출 (가능하지만 권장하지 않음)
obj._display() # 출력: Value: 10
# 자식 클래스에서 Protected 속성 접근
obj.show() # 출력: SubClass Value: 10
3.1.3 Private
클래스 내부에서만 접근 가능. 이름 앞에 밑줄 두 개(__)를 붙여 표시.
외부에서 접근 불가
class MyClass:
def __init__(self, value):
self.__value = value # Private 속성
def __display(self):
print(f"Value: {self.__value}") # Private 메서드
def get_value(self):
return self.__value # Private 속성 접근 메서드
def show(self):
self.__display() # Private 메서드 호출 메서드
# 객체 생성
obj = MyClass(10)
# Private 속성 접근 (불가능)
# print(obj.__value) # AttributeError
# Private 메서드 호출 (불가능)
# obj.__display() # AttributeError
# Private 속성 접근 메서드를 통해 접근
print(obj.get_value()) # 출력: 10
# Private 메서드 호출 메서드를 통해 호출
obj.show() # 출력: Value: 10
3.2 Getter와 Setter 메서드
클래스의 속성에 대한 접근과 수정을 제어하기 위해서 사용한다.
속성 값을 읽거나 수정할 때 추가적인 검증이나 처리를 할 수 있다.
3.2.1 필요성
- 데이터 보호
직접 속성에 접근하는 것을 방지하여 데이터의 무결성을 유지합니다.
- 검증 로직 추가
속성 값을 설정하거나 가져올 때 검증 로직을 추가할 수 있습니다.
- 캡슐화
클래스의 내부 구현을 숨기고, 인터페이스를 통해서만 상호작용하도록 합니다.
3.2.2 정의하기
- Getter 메서드
속성 값을 안전하게 읽기 위해 사용된다.
- Setter 메서드
속성 값을 안전하게 수정하기 위해서 사용
class MyClass:
def __init__(self, value):
self.__value = value # Private 속성
# Getter 메서드
def get_value(self):
return self.__value
# Setter 메서드
def set_value(self, value):
if value < 0:
raise ValueError("Value cannot be negative")
self.__value = value
# 객체 생성
obj = MyClass(10)
# Getter 메서드 호출
print(obj.get_value()) # 출력: 10
# Setter 메서드 호출
obj.set_value(20)
print(obj.get_value()) # 출력: 20
# Setter 메서드 호출 (예외 발생)
# obj.set_value(-5) # ValueError: Value cannot be negative
3.2.3 property 데코레이터 사용하기
데코레이터를 사용하여 Getter, Setter 메서드를 간편하게 정의할 수 있다.
class MyClass:
def __init__(self, value):
self.__value = value # Private 속성
@property
def value(self):
return self.__value
@value.setter
def value(self, value):
if value < 0:
raise ValueError("Value cannot be negative")
self.__value = value
# 객체 생성
obj = MyClass(10)
# 프로퍼티 접근 (Getter)
print(obj.value) # 출력: 10
# 프로퍼티 설정 (Setter)
obj.value = 20
print(obj.value) # 출력: 20
# 프로퍼티 설정 (Setter, 예외 발생)
# obj.value = -5 # ValueError: Value cannot be negative
'Language > Python' 카테고리의 다른 글
[Python] 이터레이터, 제너레이터, 데코레이터 (0) | 2024.04.28 |
---|---|
[Python] 매직 메소드 (0) | 2024.04.28 |
[Python] 클래스 (1/2) (0) | 2024.04.27 |
[Python] 패키지 설치 및 관리 (0) | 2024.04.27 |
[Python] 모듈과 패키지 (0) | 2024.04.27 |