상속과 다형성

상속과 다형성 – 이것은 파이썬에서 매우 중요한 개념입니다. 배우고 싶다면 더 잘 이해해야합니다.

계승

객체 지향 프로그래밍의 주요 장점 중 하나는 재사용입니다. 상속은이를 달성하기위한 메커니즘 중 하나입니다. 상속을 통해 프로그래머는 먼저 일반 또는 기본 클래스를 만든 다음 나중에 더 전문화 된 클래스로 확장 할 수 있습니다. 프로그래머가 더 나은 코드를 작성할 수 있습니다.

상속을 사용하면 기본 클래스에서 사용할 수있는 모든 데이터 필드와 메서드를 사용하거나 상속 할 수 있습니다. 나중에 자신의 메서드와 데이터 필드를 추가 할 수 있으므로 상속은 코드를 처음부터 다시 작성하는 대신 코드를 구성하는 방법을 제공합니다.

객체 지향 용어에서 클래스 X가 클래스 Y를 확장 할 때 Y는 수퍼 / 부모 / 기본 클래스라고하고 X는 하위 클래스 / 자식 / 파생 클래스라고합니다. 여기서 주목해야 할 점은 프라이빗이 아닌 데이터 필드와 메서드 만 자식 클래스에서 액세스 할 수 있다는 것입니다. 개인 데이터 필드 및 메서드는 클래스 내에서만 액세스 할 수 있습니다.

파생 클래스를 만드는 구문은-

class BaseClass:
   Body of base class
class DerivedClass(BaseClass):
   Body of derived class

속성 상속

이제 아래 예를보십시오-

산출

먼저 Date라는 클래스를 만들고 객체를 인수로 전달합니다. here-object는 Python에서 제공하는 내장 클래스입니다. 나중에 우리는 time이라는 또 다른 클래스를 만들고 Date 클래스를 인수로 호출했습니다. 이 호출을 통해 Date 클래스의 모든 데이터 및 속성에 대한 Time 클래스에 액세스 할 수 있습니다. 그 때문에 우리가 이전에 생성 한 Time 클래스 객체 tm에서 get_date 메소드를 얻으려고 할 때 가능합니다.

Object.Attribute 조회 계층

  • 인스턴스
  • 클래스
  • 이 클래스가 상속하는 모든 클래스

상속 예

상속 예제를 살펴 보겠습니다.

예제에 참여하기 위해 몇 개의 클래스를 만들어 봅시다.

  • 동물-클래스는 동물을 시뮬레이션
  • Cat − 동물의 하위 클래스
  • 개-동물의 하위 클래스

Python에서 객체 (인스턴스)를 생성하고 속성 값을 할당하는 데 사용되는 클래스 생성자입니다.

하위 클래스의 생성자는 항상 상위 클래스의 생성자에게 호출되어 상위 클래스의 속성 값을 초기화 한 다음 해당 속성에 대한 값을 할당하기 시작합니다.

산출

위의 예에서는 모든 하위 클래스 또는 하위 클래스가 상위 클래스에서 해당 속성을 상속하도록 부모 클래스에 넣은 명령 속성 또는 메서드를 볼 수 있습니다.

하위 클래스가 다른 하위 클래스에서 메서드 나 데이터를 상속하려고하면 Dog 클래스가 해당 cat 클래스에서 swatstring () 메서드를 호출하려고 할 때 볼 수 있듯이 오류가 발생합니다 (우리의 경우 AttributeError와 같은).

다형성 ( "다양한 모양")

다형성은 클래스 또는 하위 클래스에서 일반적으로 명명 된 메서드가있을 때 사용되는 Python 클래스 정의의 중요한 기능입니다. 이를 통해 함수는 서로 다른 시간에 서로 다른 유형의 엔티티를 사용할 수 있습니다. 따라서 유연성과 느슨한 결합을 제공하여 시간이 지남에 따라 코드를 확장하고 쉽게 유지 관리 할 수 ​​있습니다.

이를 통해 함수는 클래스 간의 구별을 인식 할 필요없이 이러한 다형성 클래스의 객체를 사용할 수 있습니다.

다형성은 상속을 통해 수행 할 수 있으며 하위 클래스는 기본 클래스 메서드를 사용하거나 재정의합니다.

이전 상속 예제를 통해 다형성의 개념을 이해하고 두 하위 클래스에 show_affection이라는 공통 메서드를 추가합니다.

우리가 볼 수있는 예제에서, 그것은 같은 방법 (아래 예제에서 show_affection)이기 때문에 같은 이름의 메서드 나 공통 인터페이스로 같은 방식으로 또는 좀 더 구체적으로 둘 이상의 클래스로 처리 할 수있는 유형이 다른 객체를 디자인하는 것을 의미합니다. 두 유형의 객체와 함께 호출됩니다.

산출

따라서 모든 동물은 애정을 나타내지 만 (show_affection) 다르게 행동합니다. 따라서“show_affection”행동은 동물에 따라 다르게 행동한다는 점에서 다형성입니다. 따라서 추상적 인 "동물"개념은 실제로 "show_affection"이 아니라 특정 동물 (개, 고양이 등)이 "show_affection"작업을 구체적으로 구현합니다.

파이썬 자체에는 다형성 클래스가 있습니다. 예를 들어, len () 함수는 여러 개체와 함께 사용할 수 있으며 모두 입력 매개 변수를 기반으로 올바른 출력을 반환합니다.

재정의

Python에서 하위 클래스에 슈퍼 클래스의 메서드를 재정의하는 메서드가 포함되어 있으면 다음을 호출하여 슈퍼 클래스 메서드를 호출 할 수도 있습니다.

self.method 대신 Super (Subclass, self) .method.

class Thought(object):
   def __init__(self):
      pass
   def message(self):
      print("Thought, always come and go")

class Advice(Thought):
   def __init__(self):
      super(Advice, self).__init__()
   def message(self):
      print('Warning: Risk is always involved when you are dealing with market!')

생성자 상속

이전 상속 예제에서 보면 __init__는 상위 클래스의 상위 클래스에 위치했습니다. 자식 클래스 dog 또는 cat에 __init__ 메서드가 없기 때문입니다. 파이썬은 동물 클래스에서 __init__를 찾기 위해 상속 속성 조회를 사용했습니다. 자식 클래스를 만들었을 때, 먼저 dog 클래스에서 __init__ 메서드를 봤지만 찾지 못한 다음 부모 클래스 Animal을 살펴보고 거기에서 찾아서 호출했습니다. 따라서 클래스 디자인이 복잡 해짐에 따라 먼저 부모 클래스 생성자를 통해 처리 한 다음 자식 클래스 생성자를 통해 인스턴스를 초기화 할 수 있습니다.

산출

위의 예에서 모든 동물에는 이름이 있고 모든 개는 특정 품종을 가지고 있습니다. super로 부모 클래스 생성자를 호출했습니다. 그래서 개는 자신의 __init__를 가지고 있지만 가장 먼저 일어나는 일은 우리가 super라고 부르는 것입니다. Super는 함수에 내장되어 있으며 클래스를 수퍼 클래스 또는 상위 클래스에 연결하도록 설계되었습니다.

이 경우에 우리는 dog의 슈퍼 클래스를 얻고 여기서 말하는 생성자 __init__에 dog 인스턴스를 전달한다고 말합니다. 즉, dog 객체로 부모 클래스 Animal __init__을 호출합니다. 개 인스턴스에 Animal __init__라고 말하지 않는 이유를 물어볼 수 있습니다. 우리는 이렇게 할 수 있습니다.하지만 동물 클래스의 이름이 나중에 변경 될 경우. 클래스 계층 구조를 재정렬하고 싶다면 개가 다른 클래스에서 물려 받았습니다. 이 경우 super를 사용하면 모듈을 유지하고 변경 및 유지 관리가 쉽습니다.

따라서이 예에서는 일반적인 __init__ 기능을보다 구체적인 기능과 결합 할 수 있습니다. 이를 통해 코드 중복을 제거하고 시스템 전체 설계를 반영하는 방식으로 클래스를 서로 연결할 수있는 특정 기능에서 공통 기능을 분리 할 수 ​​있습니다.

결론

  • __init__는 다른 방법과 같습니다. 상속 될 수있다

  • 클래스에 __init__ 생성자가 없으면 Python은 부모 클래스를 확인하여 찾을 수 있는지 확인합니다.

  • 하나를 찾으면 Python이 호출하고 검색을 중지합니다.

  • super () 함수를 사용하여 부모 클래스의 메서드를 호출 할 수 있습니다.

  • 우리 자신의 클래스뿐만 아니라 부모에서도 초기화하고 싶을 수 있습니다.

다중 상속 및 조회 트리

이름에서 알 수 있듯이 다중 상속은 Python이 클래스가 여러 클래스에서 상속되는 경우입니다.

예를 들어, 자녀는 부모 (어머니와 아버지) 모두로부터 성격 특성을 상속받습니다.

Python 다중 상속 구문

클래스가 여러 부모 클래스에서 상속되도록하려면 정의하는 동안 파생 클래스에 괄호 안에 이러한 클래스의 이름을 씁니다. 이러한 이름은 쉼표로 구분합니다.

아래는 그 예입니다.

>>> class Mother:
   pass

>>> class Father:
   pass

>>> class Child(Mother, Father):
   pass

>>> issubclass(Child, Mother) and issubclass(Child, Father)
True

다중 상속은 둘 이상의 클래스에서 상속하는 능력을 나타냅니다. 자식은 부모에서 상속하고 부모는 조부모 클래스에서 상속함에 따라 복잡성이 발생합니다. 파이썬은 객체에서 읽기를 요청하는 속성을 찾는 상속 트리를 올라갑니다. 인스턴스, 클래스 내에서 부모 클래스, 마지막으로 조부모 클래스에서 확인합니다. 이제 수업이 검색되는 순서, 즉 호흡 우선 또는 깊이 우선에 대한 질문이 발생합니다. 기본적으로 Python은 깊이 우선을 사용합니다.

이것이 바로 아래 다이어그램에서 파이썬이 클래스 A에서 dothis () 메서드를 먼저 검색하는 이유입니다. 따라서 아래 예제의 메서드 확인 순서는 다음과 같습니다.

Mro- D→B→A→C

아래의 다중 상속 다이어그램을보십시오-

Python의 "mro"기능을 이해하기 위해 예제를 살펴 보겠습니다.

산출

예제 3

"다이아몬드 모양"다중 상속의 또 다른 예를 살펴 보겠습니다.

위의 다이어그램은 모호한 것으로 간주됩니다. 이전 예에서 "방법 확인 순서"를 이해했습니다. 즉, mro는 D → B → A → C → A가되지만 그렇지 않습니다. C에서 두 번째 A를 가져 오면 Python은 이전 A를 무시하므로이 경우 mro는 D → B → C → A가됩니다.

위의 다이어그램을 기반으로 예제를 만들어 보겠습니다.

산출

위의 출력을 이해하기위한 간단한 규칙은 동일한 클래스가 메서드 확인 순서에 나타나면이 클래스의 이전 모양이 메서드 확인 순서에서 제거된다는 것입니다.

결론적으로-

  • 모든 클래스는 여러 클래스에서 상속 할 수 있습니다.

  • 파이썬은 일반적으로 상속 클래스를 검색 할 때 "깊이 우선"순서를 사용합니다.

  • 그러나 두 클래스가 동일한 클래스에서 상속 될 때 Python은 mro에서 해당 클래스의 첫 출현을 제거합니다.

데코레이터, 정적 및 클래스 메서드

함수 (또는 메서드)는 def 문으로 생성됩니다.

메서드는 메서드 첫 번째 인수가 인스턴스 객체 인 한 지점을 제외하고는 함수와 정확히 동일한 방식으로 작동합니다.

우리는 그들이 어떻게 행동하는지에 따라 메소드를 분류 할 수 있습니다.

  • Simple method− 클래스 외부에서 정의 됨. 이 함수는 인스턴스 인수를 제공하여 클래스 속성에 액세스 할 수 있습니다.

def outside_func(():
  • Instance method

def func(self,)
  • Class method − 클래스 속성을 사용해야하는 경우

@classmethod
def cfunc(cls,)
  • Static method − 수업에 대한 정보가 없습니다.

@staticmethod
def sfoo()

지금까지 인스턴스 메서드를 살펴 보았습니다. 이제 다른 두 메서드에 대한 통찰력을 얻을 시간입니다.

수업 방법

@classmethod 데코레이터는 호출 된 클래스 또는 첫 번째 인수로 호출 된 인스턴스의 클래스를 전달하는 내장 함수 데코레이터입니다. 이 평가의 결과는 함수 정의에 영향을 미칩니다.

통사론

class C(object):
   @classmethod
   def fun(cls, arg1, arg2, ...):
      ....
fun: function that needs to be converted into a class method
returns: a class method for function

이 cls 인수에 대한 액세스 권한이 있으며 개체 인스턴스 상태를 수정할 수 없습니다. 그것은 자신에 대한 접근을 필요로 할 것입니다.

  • 클래스의 객체가 아니라 클래스에 바인딩됩니다.

  • 클래스 메서드는 클래스의 모든 인스턴스에 적용되는 클래스 상태를 계속 수정할 수 있습니다.

정적 방법

정적 메소드는 self 또는 cls (class) 매개 변수를 사용하지 않지만 임의의 수의 다른 매개 변수를 허용 할 수 있습니다.

syntax

class C(object):
   @staticmethod
   def fun(arg1, arg2, ...):
   ...
returns: a static method for function funself.
  • 정적 메서드는 개체 상태 나 클래스 상태를 수정할 수 없습니다.
  • 액세스 할 수있는 데이터에 제한이 있습니다.

무엇을 사용해야 하는가

  • 일반적으로 클래스 메서드를 사용하여 팩토리 메서드를 만듭니다. 팩토리 메서드는 다양한 사용 사례에 대해 클래스 개체 (생성자와 유사)를 반환합니다.

  • 일반적으로 정적 메서드를 사용하여 유틸리티 함수를 만듭니다.