Python & Ruby

Override

오버라이드의 소개

 오버라이드의 형식

Python

Override/1.py

class C1:
    def m(self):
        return 'parent'
class C2(C1):
    def m(self):
        return super().m() + ' child'
    pass
o = C2()
print(o.m())

Ruby

Override/1.rb

class C1
  def m()
    return 'parent'
  end
end
class C2 < C1
  def m()
    return super()+' child'
  end
end
o = C2.new()
p o.m()

실행결과

parent child

Python | Ruby

오버라이드의 활용 (Python)

Override/2.py 

class Cal(object):
    _history = []
    def __init__(self, v1, v2):
        if isinstance(v1, int):
            self.v1 = v1
        if isinstance(v2, int):
            self.v2 = v2
    def add(self):
        result = self.v1+self.v2
        Cal._history.append("add : %d+%d=%d" % (self.v1, self.v2, result))
        return result
    def subtract(self):
        result = self.v1-self.v2
        Cal._history.append("subtract : %d-%d=%d" % (self.v1, self.v2, result))
        return result
    def setV1(self, v):
        if isinstance(v, int):
            self.v1 = v
    def getV1(self):
        return self.v1
    @classmethod
    def history(cls):
        for item in Cal._history:
            print(item)
    def info(self):
        return "Cal => v1 : %d, v2 : %d" % (self.v1, self.v2)
class CalMultiply(Cal):
    def multiply(self):
        result = self.v1*self.v2
        Cal._history.append("multiply : %d*%d=%d" % (self.v1, self.v2, result))
        return result
    def info(self):
        return "CalMultiply => %s" % super().info()
class CalDivide(CalMultiply):
    def divide(self):
        result = self.v1/self.v2
        Cal._history.append("divide : %d/%d=%d" % (self.v1, self.v2, result))
        return result
    def info(self):
        return "CalDivide => %s" % super().info()

c0 = Cal(30, 60)
print(c0.info())
c1 = CalMultiply(10,10)
print(c1.info())
c2 = CalDivide(20,10)
print(c2.info())

Cal => v1 : 30, v2 : 60
CalMultiply => Cal => v1 : 10, v2 : 10
CalDivide => CalMultiply => Cal => v1 : 20, v2 : 10

ideone.com

오버라이드의 활용 (Ruby)

Override/2.rb 

class Cal
  attr_reader :v1, :v2
  attr_writer :v1
  @@_history = []
  def initialize(v1,v2)
    @v1 = v1
    @v2 = v2
  end
  def add()
    result = @v1+@v2
    @@_history.push("add : #{@v1}+#{@v2}=#{result}")
    return result
  end
  def subtract()
    result = @v1-@v2
    @@_history.push("subtract : #{@v1}-#{@v2}=#{result}")
    return result
  end
  def setV1(v)
    if v.is_a?(Integer)
      @v1 = v
    end
  end
  def getV1()
    return @v1
  end
  def Cal.history()
    for item in @@_history
      p item
    end
  end
  def info()
    return "Cal => v1 : #{@v1}, v2 : #{@v2}"
  end
end
class CalMultiply < Cal
  def multiply()
    result = @v1*@v2
    @@_history.push("multipy : #{@v1}*#{@v2}=#{result}")
    return result
  end
  def info()
    return "CalMultiply => #{super()}"
  end
end
class CalDivide < CalMultiply
  def divide()
    result = @v1/@v2
    @@_history.push("divide : #{@v1}/#{@v2}=#{result}")
    return result
  end
  def info()
    return "CalDivide => #{super()}"
  end
end
c0 = Cal.new(30, 60)
p c0.info()
c1 = CalMultiply.new(10, 10)
p c1.info()
c2 = CalDivide.new(20, 10)
p c2.info()

ideone.com

 참고

github

댓글

댓글 본문
  1. Sansol Park
    하위 클래스가 상위 클래스에서 이미 정의된 `__init__` 메서드를 그대로 사용할 경우, 하위 클래스에서 `__init__` 메서드를 정의할 필요가 없습니다. 상위 클래스의 `__init__` 메서드가 하위 클래스의 인스턴스를 초기화할 때 그대로 사용되기 때문입니다.

    ### 상속과 `__init__` 메서드
    - **상위 클래스**에서 `__init__` 메서드가 정의되어 있으면, 하위 클래스는 이를 자동으로 상속받습니다. 하위 클래스가 `__init__` 메서드를 따로 정의하지 않으면, 상위 클래스의 `__init__` 메서드가 하위 클래스의 객체 초기화에 사용됩니다.

    - **하위 클래스**가 `__init__` 메서드를 따로 정의하면, 상위 클래스의 `__init__` 메서드를 덮어쓰게 됩니다. 그러나, 하위 클래스에서 상위 클래스의 초기화 동작을 유지하면서 추가적인 초기화 작업을 하고 싶다면, 하위 클래스의 `__init__` 메서드에서 `super()`를 사용하여 상위 클래스의 `__init__` 메서드를 호출할 수 있습니다.

    ### 예시

    상위 클래스 `Cal`에서 `__init__` 메서드가 정의되어 있고, 하위 클래스 `CalMultiply`와 `CalDivide`에서는 `__init__` 메서드를 따로 정의하지 않았습니다. 이 경우, 하위 클래스의 인스턴스를 생성할 때도 상위 클래스의 `__init__` 메서드가 호출되어 `v1`과 `v2`의 초기화가 이루어집니다.

    ```python
    class Cal(object):
    def __init__(self, v1, v2):
    if isinstance(v1, int):
    self.v1 = v1
    if isinstance(v2, int):
    self.v2 = v2
    # 기타 메서드들...

    class CalMultiply(Cal):
    def multiply(self):
    return self.v1 * self.v2
    # 기타 메서드들...

    class CalDivide(CalMultiply):
    def divide(self):
    return self.v1 / self.v2
    # 기타 메서드들...
    ```

    ### 하위 클래스에서 `__init__` 메서드를 정의할 필요가 있는 경우
    하위 클래스에서 `__init__` 메서드를 정의해야 하는 경우는 다음과 같습니다:
    1. 하위 클래스에서 상위 클래스의 초기화 외에 **추가적인 속성**이나 **초기화 작업**이 필요한 경우.
    2. 상위 클래스의 `__init__` 메서드를 **변경**하거나 **확장**해야 하는 경우.

    이 경우, 하위 클래스의 `__init__` 메서드에서 `super()`를 사용하여 상위 클래스의 초기화를 먼저 수행한 후, 하위 클래스의 고유한 초기화를 추가할 수 있습니다.

    ### 예시

    ```python
    class Cal(object):
    def __init__(self, v1, v2):
    if isinstance(v1, int):
    self.v1 = v1
    if isinstance(v2, int):
    self.v2 = v2

    class CalMultiply(Cal):
    def __init__(self, v1, v2, v3):
    super().__init__(v1, v2) # 상위 클래스의 초기화
    self.v3 = v3 # 하위 클래스의 고유한 초기화

    def multiply_all(self):
    return self.v1 * self.v2 * self.v3
    ```

    이 예제에서 `CalMultiply` 클래스는 `v3`라는 추가 속성을 초기화하기 위해 `__init__` 메서드를 재정의하였고, 상위 클래스 `Cal`의 초기화는 `super()`를 통해 수행되었습니다.

    따라서, 하위 클래스가 상위 클래스의 `__init__` 메서드를 충분히 커버할 수 있다면 재정의할 필요가 없지만, 그렇지 않은 경우에는 하위 클래스에서 `__init__` 메서드를 재정의해야 합니다.
    대화보기
    • Byunghawk Lee
      하위 클래스는 def __init__(self, v1, v2): 를 정의할 필요가 없나요? 상위에서 상속받아서요?
    • 냥더쿠
      내용은 이해가는데 예제의 양이 전의를 상실하게 만드네요..
      210807 완료
    • 미뇨르
      210710 완료!!
    • 정효빈
      잘들었습니다!!
    • 드림보이
      잘 들었습니다..
    • 홍주호
      20.12.13 완료
    • 윤유상
      자식 클래스가 부모 클래스와 같은 이름의 메소드를 만들면 자식 클래스의 메소드가 부모 클래스의 메소드를 override해서 자식 클래스의 메소드가 실행된다. 부모 클래스에서 같은 이름의 메소드를 실행시키기 위해서 파이썬은 super().메소드명()을 사용하고, 루비는 super()만 사용한다. 파이썬의 super()는 부모클래스 자체를 가리키는 반면, 루비의 super()는 super()가 쓰인 메소드와 같은 이름의 부모 클래스 메소드를 불러온다. 감사합니다!
    • 양민
      20/12/06
    • cgoing
      cgoing / 2020.09.29
    • 허우룩
      2020.09.24
    • PlayerSEAN
      쿠키앤크림님 따라잡기
      2020/08/08 완료
    • 쿠키앤크림
      pupu님 따라잡기
      2020/07/04 완료
    • 김광현
      6/6완료
    • 에우젠
      기본적으로 아톰은 현재 OS에 이미 설치된 2.x 버전으로 코드를 실행합니다. 따라서 코드를 실행하는 파이썬 엔진의 버전을 변경할 필요가 있는데요, 아래 링크를 보시고 따라하시면 됩니다. 링크가 이해 안 되시는 분은 구글에서 atom python3 이라고 치시고 검색해보시면 비슷한 해결법이 많이 나오니 참고하시면 되겠습니다.
      https://hellobaek.tistory.com/7
      대화보기
      • oxugi
        2020/04/28 완료
      • 맥반장
        2020-04-04 한 번에 이해하기가 어렵네요. 여러 번 반복해서 수강할 듯 싶습니다ㅜㅜ
      • liero1p
        근데 atom 에서는 typeError 가 나는데 terminal에서 파이썬 파일을 실행하면 문제없이 결과가 잘 출력되는 경우가 종종 있네요. 이건 atom 설정을 바꿔주면 괜찮아질 것 같은데.. 혹시 방법을 아시는 분이 있을까요?
      • 가재준
        완료
      • 홍주호
        20190825 완료
      • 허니비
        190808
      • 얼그레이
        오버라이드 기능 매우 재밌네요!! 감사합니다 :)
        190607
      • Hotak Choi
        19/05/11 !감사합니다
      • huyk
        190503완료 감사합니다
      • wiseman
        190420 2300 완료
      • 19.04.20 완료
      • 호두
        고맙습니다
      • 정돌
        좋아요!
        ^^*!
      • kmw8462
        감사합니다.
      • yareuk
        2018-12-26
      • 닐반
        2018. 10. 14.
      • 유닉스가이
        감사합니다.
      • Ji Yeoun Park
        2018.7.03 감사합니다.
      • 정병찬
        2018 06 28
        수강완료
      • 언어정복자
        2018.1.1 올해도 열공 할게요.
      • remake
        뒷 수업 실습하다가 원인을 알았습니다.
        ruby로 실행되어야 했는데, ruby rails라는 걸로 실행이 되었던 거였군요.
        대화보기
        • remake
          1.rb 아톰에서 돌리니까 결과가 깨져 나오네요.
          'rails'��(��) ���� �Ǵ� �ܺ� ���, ������ �� �ִ� ���α׷�, �Ǵ�
          ��ġ ������ �ƴմϴ�.

          커맨드창 띄우고 돌리면 정상으로 나오는데, 다른 분들도 아톰에서 결과가 깨져 나오는지, 어떻게 하면 정상으로 나오게 할 수 있는지 궁금합니다.

          2.rb도 마찬가지네요.
        • 성현아빠
          완료
        • GoldPenguin
          완료햤습니다.
        • 박정우
          너무 좋은 강의 잘 듣고 혼자 공부하는데 많은 도움 받고 있습니다.
          예제를 참 이해하기 쉽고 실습에 도움이 되게 만드셨네요.
          감사합니다.
        • 김태윤
          완료했어요
        • 미림_likelion
          수강 완료했습니다. 감사합니다.
        • 심화평
          2017.07.06 감사합니다~
        • 나만의 부
          2017.4.30 감사합니다~
        • Ino Jeong
          맥이나 리눅스 쓰시는 분들은 터미널에서 직접 python3 override.py 이런식으로 실행해보시면 잘 돌아가는걸 확인하실 수 있을거에요. 아톰에서는 기본으로 설치되어있는 python 2.x 버젼으로 실행해서 super() 쓸 때 에러나는 경우가 있더라고요.
        • 컴맹공돌
          python 3 버전을 쓰는데도 계속 super() takes at least 1 argument (0 given)이러한 오류가 나서 진도를 나가지를 못하고 있네요.
          인터넷에서 찾아봐도 3.0버전에서 개선이 되서 super() 저 괄호 안에 특정 요소가 없어도 이고잉 님의 코드대로 적으면 오류가 안 날 것 같은데 계속 나는 이유 혹시 알 수 있을까요?
        • 문돌이
          감사합니다 잘 이해하였습니다 :)
        • Philip Oh
          감사합니다:)
        • 환글
          Override 가 그런 뜻이었군요 고맙습니다~~~
        • Mike Kang
          감사합니다 항상 잘 보고 있습니다