출처 :https://www.pythontutorial.net/python-oop/python-overriding-method/
Introduction to Python overridding method
overriding method(재정의하는 메서드)를 사용하면 sub 클래스가 parent 클래스 중 하나에서 이미 제공하는 메서드의 특정 구현을 제공할 수 있습니다.
overriding method을 더 잘 이해하기 위해 예를 들어 보겠습니다.
먼저 Employee 클래스를 정의합니다.
class Employee:
def __init__(self, name, base_pay):
self.name = name
self.base_pay = base_pay
def get_pay(self):
return self.base_pay
Employee 클래스에는 두 개의 인스턴스 변수 (이름, base_pay)가 있습니다. 또한 base_pay 반환하는 get_pay() 메서드도 있습니다.
둘째, Employee 클래스에서 상속되는 SalesEmployee를 정의합니다.
class SalesEmployee(Employee):
def __init__(self, name, base_pay, sales_incentive):
self.name = name
self.base_pay = base_pay
self.sales_incentive = sales_incentive
클래스에는 이름, base_pay 및 sales_incentive의 세 가지 인스턴스 속성이 있습니다.
셋째, SalesEmployee 클래스의 새 인스턴스를 만들고 급여를 표시합니다.
john = SalesEmployee('John', 5000, 1500)
print(john.get_pay())
Output:
5000
get_pay()메소드는 base_pay와 sales_incentive의 합이 아닌 base_pay 만 반환합니다.
SalesEmployee 클래스의 인스턴스에서 get_pay()를 호출하면 파이썬 은 Employee 클래스의 get_pay() 메서드를 실행하여 base_pay 반환합니다.
급여에 판매 인센티브를 포함하려면 다음과 같이 SalesEmployee 클래스에서 get_pay() 메서드를 다시 정의해야 합니다.
class SalesEmployee(Employee):
def __init__(self, name, base_pay, sales_incentive):
self.name = name
self.base_pay = base_pay
self.sales_incentive = sales_incentive
def get_pay(self):
return self.base_pay + self.sales_incentive
이 경우 SalesEmployee 클래스의 get_pay() 메서드가 Employee 클래스의 get_pay() 메서드를 overriding한다고 말합니다 .
SalesEmployee 객체의 get_pay() 메서드를 호출하면 Python은 SalesEmployee 클래스에서 get_pay() 메서드를 호출합니다.
john = SalesEmployee('John', 5000, 1500)
print(john.get_pay())
Output:
6500
Employee 클래스의 인스턴스를 만드는 경우 Python은 SalesEmployee 클래스의 get_pay() 메서드가 아닌 Employee 클래스의 get_pay() 메서드를 호출 합니다 . 예를 들어:
jane = Employee('Jane', 5000)
print(jane.get_pay())
전체 Code
class Employee:
def __init__(self, name, base_pay):
self.name = name
self.base_pay = base_pay
def get_pay(self):
return self.base_pay
class SalesEmployee(Employee):
def __init__(self, name, base_pay, sales_incentive):
self.name = name
self.base_pay = base_pay
self.sales_incentive = sales_incentive
def get_pay(self):
return self.base_pay + self.sales_incentive
if __name__ == '__main__':
john = SalesEmployee('John', 5000, 1500)
print(john.get_pay())
jane = Employee('Jane', 5000)
print(jane.get_pay())
Advanced method overriding example
다음은 Parser 클래스를 정의합니다.
import re
class Parser:
def __init__(self, text):
self.text = text
def email(self):
match = re.search(r'[a-z0-9\.\-+_]+@[a-z0-9\.\-+_]+\.[a-z]+', self.text)
if match:
return match.group(0)
return None
def phone(self):
match = re.search(r'\d{3}-\d{3}-\d{4}', self.text)
if match:
return match.group(0)
return None
def parse(self):
return {
'email': self.email(),
'phone': self.phone()
}
Parser 클래스에는 구문 분석할 텍스트 조각을 지정하는 속성 text가 있습니다. 또한 Parser 클래스에는 세 가지 메서드가 있습니다.
- email() 메서드는 text를 구문 분석하고 이메일을 반환합니다.
- phone() 메서드는 text를 구문 분석하고 nnn-nnnn-nnnn 형식의 전화 번호를 반환합니다. 여기서 n은 0에서 9 사이의 숫자입니다(예: 408-205-5663).
- parse()메소드는 이메일과 전화의 두 요소를 포함하는 사전을 반환합니다. email() 및 phone() 메서드를 호출하여 text 속성에서 이메일과 전화를 추출합니다.
다음은 Parser 클래스를 사용하여 전자 메일 및 전화를 추출합니다.
s = 'Contact us via 408-205-5663 or email@test.com'
parser = Parser(s)
print(parser.parse())
Output:
{'email': 'email@test.com', 'phone': '408-205-5663'}
영국 전화 번호 형식인 n-nnn-nnn-nnn 형식으로 전화 번호를 추출해야 한다고 가정합니다. 또한 Parser 클래스와 같은 추출 이메일을 사용하려고합니다.
이를 위해 Parser 클래스 에서 상속되는 UkParser라는 새 클래스를 정의할 수 있습니다 . UkParser 클래스에서 다음과 같이 phone() 메서드를 overriding합니다.
class UkParser(Parser):
def phone(self):
match = re.search(r'(\+\d{1}-\d{3}-\d{3}-\d{4})', self.text)
if match:
return match.group(0)
return None
다음은 UkParser 클래스를 사용하여 텍스트에서 전화 번호 (영국 형식)와 전자 메일을 추출합니다.
s2 = 'Contact me via +1-650-453-3456 or email@test.co.uk'
parser = UkParser(s2)
print(parser.parse())
Output:
{'email': 'email@test.co.uk', 'phone': '+1-650-453-3456'}
이 예제에서 Parser는 Parser 클래스인 부모 클래스에서 parse() 메서드를 호출 합니다. 차례로 parse() 메서드는 email() 및 phone() 메서드를 호출합니다 .
그러나 Parser()는 Parser 클래스의 phone() 메서드를 호출 하지 않고 UkParser 클래스의 phone() 메서드를 호출 합니다.
parser.parse()
그 이유는 parse() 메서드 내에서 self가 UkParser 클래스의 인스턴스 인 Parser이기 때문입니다.
따라서 parse() 메서드 내에서 self.phone() 메서드를 호출하면 파이썬은 UkParser의 인스턴스에 바인딩된 phone() 메서드를 찾습니다.
전체 Code
import re
class Parser:
def __init__(self, text):
self.text = text
def email(self):
match = re.search(r'[a-z0-9\.\-+_]+@[a-z0-9\.\-+_]+\.[a-z]+', self.text)
if match:
return match.group(0)
return None
def phone(self):
match = re.search(r'\d{3}-\d{3}-\d{4}', self.text)
if match:
return match.group(0)
return None
def parse(self):
return {
'email': self.email(),
'phone': self.phone()
}
class UkParser(Parser):
def phone(self):
match = re.search(r'(\+\d{1}-\d{3}-\d{3}-\d{4})', self.text)
if match:
return match.group(0)
return None
if __name__ == '__main__':
s = 'Contact us via 408-205-5663 or email@test.com'
parser = Parser(s)
print(parser.parse())
s2 = 'Contact me via +1-650-453-3456 or email@test.co.uk'
parser = UkParser(s2)
print(parser.parse())
Overriding attributes
다음은 속성을 overriding하여 Parser 및 UkParser 클래스를 구현하는 method을 보여 줍니다.
import re
class Parser:
phone_pattern = r'\d{3}-\d{3}-\d{4}'
def __init__(self, text):
self.text = text
def email(self):
match = re.search(r'[a-z0-9\.\-+_]+@[a-z0-9\.\-+_]+\.[a-z]+', self.text)
if match:
return match.group(0)
return None
def phone(self):
match = re.search(self.phone_pattern, self.text)
if match:
return match.group(0)
return None
def parse(self):
return {
'email': self.email(),
'phone': self.phone()
}
class UkParser(Parser):
phone_pattern = r'(\+\d{1}-\d{3}-\d{3}-\d{4})'
if __name__ == '__main__':
s = 'Contact us via 408-205-5663 or email@test.com'
parser = Parser(s)
print(parser.parse())
s2 = 'Contact me via +1-650-453-3456 or email@test.co.uk'
parser = UkParser(s2)
print(parser.parse())
이 예제에서 Parser에는 클래스 변수 phone_pattern가 있습니다. Parser 클래스의 phone() 메서드는 phone_pattern 사용하여 전화 번호를 추출합니다.
UkParser 자식 클래스는 phone_pattern 클래스 속성을 overriding(또는 overriding)합니다.
UkParser의 인스턴스에서 parse() 메서드를 호출하면 parse() 메서드는 UkParser 클래스에 정의된 phone_pattern 사용하는 phone() 메서드를 호출 합니다.
Summary
- 메서드 overrding을 사용하면 자식 클래스가 부모 클래스 중 하나에서 이미 제공하는 메서드의 특정 구현을 제공할 수 있습니다.
'Python Object-oriented Programming' 카테고리의 다른 글
enumeration (0) | 2023.04.04 |
---|---|
__slots__ Method (0) | 2023.04.04 |
inheritance (0) | 2023.04.04 |
delete-property (0) | 2023.04.04 |
readonly-property (0) | 2023.04.04 |
댓글