두 클래스 사이 부모-자식 관계를 정립하는 것
클래스는 상속이 가능함
class ChildClass(ParantClass):
하위 클래스는 상위 클래스에 정의된 속성, 행동, 관계 및 제약조건을 모두 상속받음
부모 클래스의 속성, 메서드가 자식 클래스에 상속되므로, 코드 재사용성이 높아짐
두 클래스 사이에 공통부분을 뽑아 부모 클래스를 만들고 하위클래스에서 상속받으면 메서드를 재사용할 수 있음.
파이썬의 모든 클래스는 object로부터 상속됨
부모 클래스의 모든 요소(속성, 메서드)가 상속됨
super()를 통해 부모 클래스의 요소를 호출할 수 있음
메서드 오버라이딩을 통해 자식 클래스에서 재정의 가능함
상속관계에서의 이름공간은 인스턴스, 자식 클래스, 부모 클래스 순으로 탐색
상속 관련 메서드
classinfo의 instance이거나 subclass인 경우 True
class Person:
pass
class Professor(Person):
pass
class Student(Person):
pass
# 인스턴스 생성
p1 = Professor()
s1 = Student()
print(isinstance(p1, Person)) # True
print(isinstance(p1, Professor)) # True
print(isinstance(p1, Student)) # False
print(isinstance(s1, Person)) # True
print(isinstance(s1, Professor)) # False
print(isinstance(s1, Student) # True
class가 classinfo의 subclass면 True
classinfo는 클래스 객체의 튜플일 수 있으며, classinfo의 모든 항목을 검사
class Person:
pass
class Professor(Person):
pass
class Student(Person):
pass
# 인스턴스 생성
p1 = Professor()
s1 = Student()
print(issubclass(bool, int)) # True
print(issubclass(float, int)) # False
print(issubclass(Professor, Person)) # True
print(issubclass(Professor, (Person, Student))) # True
자식클래스에서 부모클래스를 사용하고 싶은 경우
class Person:
def __init__(self, name, age, number, email):
self.name = name
self.age = age
self.number = number
self.email = email
class Student(Person):
def __init__(self, name, age, number, email, student_id):
# Person 클래스
# self.name = name
# self.age = age
# self.number = number
# self.email = email
# super() 메서드를 이용해 간소화할 수 있음
super().__init__(name, age, number, email)
self.student_id = student_id
다중상속
해당 인스턴스의 클래스가 어떤 부모 클래스를 가지는지 확인하는 메서드
기존의 인스턴스 → 클래스 순으로 이름 공간을 탐색하는 과정에서 상속 관계에 있으면 인스턴스 → 자식 클래스 → 부모 클래스로 확장
class Person:
pass
class Dad(Person):
pass
class Mom(Person):
pass
class FirstChild(Dad, Mom): # Dad -> Mom 순서로 탐색 : [0]->[1]
pass
print(FirstChild.mro())
'''
[<class '__main__.FirstChild'>, <class '__main__.Dad'>,
<class '__main__.Mom'>, <class '__main__.Person'>,<class 'object'>]
'''
상속받은 메서드를 재정의 ⇒ 덮어쓰기
클래스 상속 시, 부모 클래스에서 정의한 메서드를 자식 클래스에서 변경
부모 클래스의 메서드 이름과 기본 기능은 그대로 사용하지만, 특정 기능을 바꾸고 싶을 때 사용
부모 클래스의 메서드를 실행시키고 싶은 경우 super()
를 활용
class Person:
def __init__(self, name):
self.name = name
def talk(self):
print(f'반갑습니다. {self.name}입니다.')
class Professor(Person):
def talk(self): # 메서드 오버라이딩(덮어쓰기)
print(f'{self.name}일세.')
class Student(Person):
def talk(self):
super().talk() # 상위 클래스인 Person의 talk() 실행
print(f'저는 학생입니다.')
p1 = Professor('김교수')
p1.talk() # 김교수일세.
s1 = Student('이학생')
s1.talk() # 반갑습니다. 이학생입니다.
# 저는 학생입니다.
객체의 일부 구현 내용에 대해 외부로부터의 직접적인 엑세스를 차단
파이썬에서 암묵적으로 존재하지만, 언어적으로는 존재하지 않음
접근 제어자 종류
Public Member
언더바 없이 시작하는 메서드나 속성
어디서나 호출이 가능, 하위 클래스 override 허용
일반적으로 작성되는 메서드와 속성의 대다수 차지
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('홍길동', 25)
print(p1.name) # 홍길동
print(p1.age) # 25
Protected Member
언더바 1개로 시작하는 메서드나 속성
암묵적 규칙에 의해 부모 클래스 내부와 자식 클래스에서만 호출 가능(오류가 발생하진 않음)
하위 클래스 override 허용
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
def get_age(self):
return self._age
# 인스턴스를 만들고 get_age 메서드를 활용하여 호출할 수 있음
p1 = Person('홍길동', 25)
print(p1.name) # 홍길동
print(p1.get_age()) # 25
# 물론 _age에 직접 접근해도 확인 가능
# 파이썬에서는 암묵적으로 활용되는 것
print(p1._age) # 25
Private Member
언더바 2개로 시작하는 메서드나 속성
본 클래스 내부에서만 사용이 가능
하위클래스 상속 및 호출 불가능(오류)
외부 호출 불가능(오류)
개발 과정에서 불필요한 변수의 접근을 막기 위함
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def get_age(self):
return self.__age # 본 클래스 내부에서만 호출 가능
# 인스턴스를 만들고 get_age 메서드를 활용하여 호출할 수 있음
p1 = Person('홍길동', 25)
print(p1.name) # 홍길동
print(p1.get_age()) # 25
# __age에 직접 접근 불가
print(p1.__age)
# AttributeError: 'Person' object has no attribute '__age'
getter 메서드와 setter 메서드
class Person:
def __init__(self, age):
self._age = age
**@property**
def age(self):
return self._age # 본 클래스 내부에서만 호출 가능
**@age.setter**
def age(self, new_age):
if new_age <= 19:
raise ValueError('Too Young')
return
self._age = new_age
# 인스턴스를 만들어서 나이에 접근하면 정상적으로 출력됨
p1 = Person(25)
print(p1.age) # 25
# p1 인스턴스의 나이를 다른 값으로 바꿔도 정상적으로 반영됨
p1.age = 33
print(p1.age) # 33
p1.age = 19
print(p1.age) # ValueError : Too Young