상세 컨텐츠

본문 제목

Object Oriented Programming 원칙 (3) - 상속(inheritance)

개발/python-객체지향프로그래밍(OOP)

by Matthew0633 2022. 5. 20. 22:11

본문

상속 Inheritance

부모 class의 속성과 행위(methods)을 그대로 상속 받고 행위(methods)의 일부분을 수정해야 할 경우 상속받은 자식 class에서 해당 행위(methods)만 다시 수정하여 사용할 수 있도록 한다. 또한 자식 class에서 추가적으로 속성이나 행위(methods)를 정의할 수 있게 한다. (method overriding)

[클래스 상속]

  • 부모 클래스가 갖는 모든 메서드와 속성이 자식 클래스에 그대로 상속된다.
  • 자식 클래스에서 별도의 메서드나 속성을 추가할 수 있다.
  • 메소드 오버라이딩
  • super()
  • Python의 모든 클래스는 object 클레스를 상속한다. : 모든 것은 객체이다.
  • 부모 클래스가 갖는 모든 메서드와 속성이 자식 클래스에 그대로 상속된다.

1. 부모 클래스가 갖는 모든 메서드와 속성이 자식 클래스에 그대로 상속된다.

class Robot:
		
    def __init__(self, name):
        self.name = name

    def say_hi(self):
        print(f"Greetings, my masters call me, {self.name}.")

class Siri(Robot):
    pass


siri = Siri("iphone8")
siri.say_hi() # "Greetings, my masters call me, iphone8."

2. 자식 클래스에서 별도의 메서드나 속성을 추가할 수 있다.

class Robot:

    def __init__(self, name):
        self.name = name

    def say_hi(self):
        print(f"Greetings, my masters call me, {self.name}.")


class Siri(Robot):
    def call_me(self):
        print("Yes, my lord?")

    @classmethod
    def hello_apple(cls):
        print(f"{cls} says, hello apple!!")


siri = Siri("iphone8")

siri.call_me() # "Yes, my lord?"
Siri.hello_apple() # "Siri says, hello apple!!"

3. 메소드 오버라이딩

class Robot:

    def __init__(self, name):
        self.name = name

    def say_hi(self):
        print(f"Greetings, my masters call me, {self.name}.")


class Siri(Robot):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hi(self):
        print(f"Greetings, my name is {self.name}. by siri.")

siri = Siri("iphone8", 17)
siri.say_hi() "Greetings, my name is iphone8. by siri."

4. super() 을 활용한 __init__ 메소드 오버라이딩

class Robot:
    def __init__(self, name):
        self.name = name

class Siri(Robot):
    def __init__(self, name, age):
        super().__init__(name)
        self.age = age

siri = Siri("iphone8", 17)

print(siri.name) # iphone8
print(siri.age) # 17

"""
Python 2:

class A:
    def __init__(self):
        ...

class B(A):
    def __init__(self):
        super(B, self).__init__()
"""

5. Python의 모든 클래스는 object 클레스를 상속한다 : 모든 것은 객체이다.

python 내 class 상속에 대해 알아보기전에, 이를 알기 위해 활용할 class.mro() 를 살펴보자. class.mro() 를 사용하면 해당 class가 상속받고 있는 모든 class 에 대해 list로 출력해준다. mro 는 method resolution order 의 줄임말이다. mro() 메소드는 해당 class 의 상속 class 정보를 담고 있는 __mro__ attribute의 값을 반환한다. 이를 활용하여 아래 예시에서 class D 는, A, B, C 3개의 class를 다중상속 받고 있는 것을 알 수 있다.

class A:
    pass


class B:
    pass


class C:
    pass

# 다중상속
class D(A, B, C):
    pass


print(D.mro()) 
"""
[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, 
<class '__main__.C'>, <class 'object'>]
"""

그런데, 마지막에 있는 object class 는 상속을 명시한적이 없는데 상속 class로 표시되어 있다. 이는 “파이썬 내에서는 모든 것이 객체이다” 라는 사실을 보여주는 예이다.

(class object) Return a new featureless object. object is a base for all classes. It has methods that are common to all instances of Python classes. This function does not accept any arguments.

(https://docs.python.org/3/library/functions.html?highlight=object#object)

object 는 파이썬 내 상속관계에서의 최상위 클래스로, 사용자가 정의하는 모든 class 는 object class를 상속받는다. object base class 는 python 내 builtin 기능을 제공하는 special method 와 특정 attribute 들을 제공하여 class 내에서 필요한 기능을 정의할 수 있도록 한다.

class Robot(object):
    def __init__(self, name):
        self.name = name

class Siri(Robot):
    def call_me(self):
        print("네?")

siri = Siri("iphone8")

print( Siri.mro() ) 
# * [<class '__main__.Siri'>, <class '__main__.Robot'>, <class 'object'>]

print(Robot.mro())  
# * [<class '__main__.Robot'>, <class 'object'>]

print(object) 
# <class 'object'>

print(dir(object))
"""
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
 '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__']
"""

print(object.__name__) # object

print(int.mro()) # [<class 'int'>, <class 'object'>]
print(int.__init__(8.9)) # None
print(int(8.9)) # 8

관련글 더보기

댓글 영역