본문 바로가기
개발/파이썬

23.03.10파이썬 상속, 스페셜메소드

by 상달군 2023. 3. 10.
728x90

목차

1. 파이썬의 객체지향 프로그래밍

  • 상속
  • 메소드 오버라이딩 
  • 다중상속

2. 파이썬의 스페셜 메소드(Special Method)

  • Special Method(스페셜 메소드)

17.상속.ipynb

 

1-1.상속

  • 기존의 정의해둔 클래스의 기능을 그대로 물려받음
  • 기존 클래스 기능 일부를 추가하거나, 변경하여 새로운 클래스를 정의할 수 있다 라는 개념
  • 코드를 재사용할 수 있게 됨
  • 안정적이고 유지보수에 용이함
  • 상속을 받고자 하는 대상인 기존 클래스를 부모,parent, super, base 클래스라고 부름
  • 상속 받는 새로운 클래스는 자식, child, sub 클래스라고 부른다.

예제 ) 잘 사용중인 Animal 클래스

  • Animal 클래스를 Dog클래스에서 사용하고 싶어 상속 하였다.
  • 단, 부모클래스를 사용할 때, 부모클래스가 가지고 있는 프로퍼티값도 함께 상속 받게 된다. 그렇기 때문에 아규먼트 값을 부모클래스에 정의 되어있는 형태로 사용해야 합니다. 만약, 형태가 다르면 오류가 발생 될수 있습니다.   
    • 부모 클래스 : Animal
    • 자식 클래스 : Dog 

  • 위에서는 아규먼트값을 주지 않아 에러가 발생 
  • 아래 그림에서 보면 정상적인 아규먼트값을 입력하니 문제 없이 사용 가능해졌습니다. 

1-2.메소드 오버라이딩 

  • 부모 클래스의 method를 재정의
  • 자식 클래스의 인스턴스로 호출재정의된 메소드가 호출됨
  • 자식 클래스에 존재 하는 메소드를 부모 클래스에서 불러와 사용할 수는 없음 

예제) 메소드 오버라이딩을 해보기 위한 기본 세팅

  • 아래줄의 코드에 주석을 해제후 다시 실행 해보겠습니다. 
def eat(self, food):             #매소드 오버라이딩
 print(f'{self.name}는 {food}를 아주~ 맛있게 먹습니다.')

  • 부모 클래스인 (=Animal)에 있는 eat메소드의 결과값이 변경 된걸 확인 할수 있습니다. 
    • 부모 클래스(=Animal)에 존재하던 eat 메소드를 자식클래스(=Dog) 에서 수정 하여 결과값이 변경 된걸 확인 하실수 있습니다. 
  • 자식 클래스에 존재 하는 메소드를 부모 클래스에서 불러와 사용할 수는 없음

1-3.다중상속

  • C#, java 프로그래밍 언어에서는 다중상속이 불가능하다.
  • 파이썬은 C++과 같이 다중상속이 가능한 언어이다.
    • 여러 클래스를 상속 가능하다. (갯수의 제한이 없다.)

//상속을 많이 받을 수록 프로그램 자체가 애매하고 어려운 소스가 될 수 있다.

 

예제) 예제를 위한 기본 클래스 생성

잘 작동 하고 있다는걸 확인 할 수 있습니다.

클래스명.mro()을 실행시 '클래스명'이 어떤 클래스를 상속 받고 있는지 확인 가능합니다. 


18.스페셜메소드.ipynb

  • '__' 언더바2
  • __로 시작해서 __로 끝나는 특수 함수  // __main__ // __init__ .....
  • 해당 메소드들을 재구현하면 객체에 여러가지 파이썬 내장 함수나 연산자에 원하는 기능을 부여할 수 있음.

예시 )

#기본 생성자있는 클래스
class Point:
  def __init__(self, x, y):
    self.x = x
    self.y = y

  def print_point(self):    #결과 값이 (3,4) 이렇게 보였으면 한다.
    print(f'({self.x} , {self.y})')

  def __str__(self):        # str() 함수를 오버라이딩 해줌.
    return (f'({self.x} , {self.y})')

  def __add__(self, pt):     # + 연산자를 오버라이딩 한다. (객체 + 객체)
    new_x = self.x + pt.x
    new_y = self.y + pt.y

    return Point(new_x, new_y)

  def __sub__(self, pt):     # - 연산자를 오버라이딩 (객체 - 객체)
    new_x = self.x - pt.x
    new_y = self.y - pt.y
    return Point(new_x, new_y)

  def __len__(self):          # len() 함수 오버라이딩 : 
    return self.x + self.y

  def __getitem__(self, index):   # 인덱싱을 오버라이딩 (객체[인덱스])   
                                                                # 지금 형태가 ( 3 , 4 ) 형식이니깐 
    if index == 0 :               # 인덱스가 0 이면 x를 출력    # x = 3
      return self.x               
    elif index == 1:              # 인덱스가 1 이면 y를 출력    # y = 4
      return self.y
    else:                         # 0 , 1 이 아니라면 -1 출력 
      return -1

 

값을 확인 해봅시니다.


p1의 객체를 생성할때 어떠한 값을 입력 받았는 확인하는 함수 호출

스페셜메소드 코드 

  def print_point(self):    #결과 값이 (3,4) 이렇게 보였으면 한다.
    print(f'({self.x} , {self.y})')

결과값 [  str()메소드를 스페셜메소드  ]

  • 스페셜 메소드가 적용 전

  • 스페셜 메소드코드 적용 후

스페셜메소드 코드

  def __str__(self):        # str() 함수를 오버라이딩 해줌.
     return (f'({self.x} , {self.y})')

결과값 [ ' + '를 스페셜메소드 ]

  • 스페셜 메소드가 적용 전 

  • 스페셜메소드가 적용 후 

스페셜메소드 코드

  def __add__(self, pt):     # + 연산자를 오버라이딩 한다. (객체 + 객체)
    new_x = self.x + pt.x
    new_y = self.y + pt.y

    return Point(new_x, new_y)

결과값 [ ' - '를 스페셜메소드 ]

  • 스페셜 메소드가 적용 전 

  • 스페셜 메소드가 적용 후

스페셜메소드 코드

  def __sub__(self, pt):     # - 연산자를 오버라이딩 (객체 - 객체)
    new_x = self.x - pt.x
    new_y = self.y - pt.y
    return Point(new_x, new_y)

결과값 [  len()함수를 스페셜메소드 ]

  • p1객체 타입 자체가 len함수를 사용할수 없기 때문에 사용할수 있게 바꾸고 싶다.
  • 스페셜 메소드가 적용 전 

  • 스페셜 메소드가 적용 후

스페셜메소드 코드

  def __len__(self):          # len() 함수 오버라이딩 : 
    return self.x + self.y

결과값 [ 인덱싱을 사용하기 위한 스페셜메소드 ]

  • 스페셜 메소드가 적용 전 

  • 스페셜 메소드가 적용 후

스페셜메소드 코드

  def __getitem__(self, index):   # 인덱싱을 오버라이딩 (객체[인덱스])   
                                                                # 지금 형태가 ( 3 , 4 ) 형식이니깐 
    if index == 0 :               # 인덱스가 0 이면 x를 출력    # x = 3
      return self.x               
    elif index == 1:              # 인덱스가 1 이면 y를 출력    # y = 4
      return self.y
    else:                         # 0 , 1 이 아니라면 -1 출력 
     return -1

 

728x90

댓글