[Python] 연습

[Python] 클래스와 상속

Simon Yoon 2022. 5. 27. 23:49
  • 상속
    • 다른 클래스의 기능을 그대로 물려받을 수 있다 → 기존 클래스에 기능 일부를 추가하거나, 변경하여 새로운 클래스를 정의한다.
    • 기존 클래스는 [Parent, Super, Base class], 상속 받는 새로운 클래스는 [Child, Sub, Derived class]라고 부른다.

1. Parent 클래스를 정의

class Parent:
    def __init__(self):
        self.i = 10

2. Parent 클래스의 인스턴스를 생성

father = Parent()
print(father.i)
# 결과: 10

3. Child 클래스를 정의

class Child(Parent):  # 상속
    pass

c = Child()
print(c.i)  # 결과: 10

Child 클래스는 Parent 클래스로부터 상속을 받았지만 pass 키워드만 작성되어 있으며 아무런 기능이 없다. 하지만 Child 클래스의 객체를 생성해 i를 출력해보면 동일하게 10이라는 결과가 나온다. 이처럼 상속을 받으면 부모 클래스의 기능을 그대로 받는다는 것을 알 수 있다.

 

  • 상속에 대한 예시
    • 바람직한 것은 부모로부터 일부 상속받고 자식 클래스에는 부모에 없던 기능이 추가되는 것이다.
class Person:
    def __init__(self, name):
        self.name = name
    def eat(self, food):
        print('{}은 {}를 먹습니다.'.format(self.name, food))
class Student(Person):
    def cook(self, food):
        print('{}은 {}를 요리합니다.'.format(self.name, food))

s = Student('bob')
s.cook('샌드위치')
s.eat('햄버거')

## bob은 샌드위치를 요리합니다.
## bob은 햄버거를 먹습니다.
  • 메소드 오버라이드(method override)
    • 부모 클래스의 method를 재정의(override, 덮어쓰기)한다.
    • 다시 작성한 메서드를 하위 클래스(자식 클래스)의 인스턴스로 호출시, 오버라이딩한 메소드가 호출된다.
class Person:
    def __init__(self, name):
        self.name = name
    def eat(self, food):
        print('{}은 {}를 먹습니다.'.format(self.name, food))
class Student(Person):
    def eat(self):
        print('맛있게 먹어요.')
    def cook(self, food):
        print('{}은 {}를 요리합니다.'.format(self.name, food))

s = Student('bob')
s.cook('샌드위치')
s.eat()

## bob은 샌드위치를 요리합니다.
## 맛있게 먹어요.
  • super()
    • 하위클래스에서 부모클래스의 메소드를 호출할 때 사용
    • super() 활용 예시
class Parent:
    def hello(self):
        print('안녕!')

class Child(Parent):
    def hello(self):
        super().hello()
        print('오늘은 날씨가 좋네요.')
    def study(self):
        print('즐거운 공부')

kim = Child()
kim.hello()

# 안녕!
# 오늘은 날씨가 좋네요.
  • 추상클래스(abstract class)
    • 추상클래스에는 미구현된 추상메소드가 포함되며, 자식 클래스에서 해당 추상 메소드를 반드시 구현하도록 한다.
    • 반드시 abc모듈을 import 해야합니다.
from abc import *
class 추상클래스명(metaclass=ABCMeta):

     @abstractmethod
        def 추상메소드(self):
            pass
  • 추상클래스 작성 예시
from abc import *

# member 변수 w, h를 갖는 Shape 클래스를 정의
class Shape(metaclass = ABCMeta):
    def __init__(self, w, h):
        self.w = w
        self.h = h

    @abstractmethod
    def draw(self):
        # Shape 클래스는 도형을 그리는 draw()라는 추상메소드를 포함
        pass

# Shape를 상속받은 Rect, Circle 클래스를 정의하고, draw() 메소드를 적절하게 구현
class Rect(Shape):
    def draw(self, w, h):
        print('사각형')
    
    def calculator(self):
        return self.w * self.h

class Circle(Shape):
    def __init__(self, r):
        # super().__init__(w, h)
        self.r = r

    def draw(self):
        print('원형')
    
    def calculator(self):
        return (self.r**2)*3.141592

t = Rect(2, 4)
print(t.calculator())
# 8
    
c = Circle(3)
c.draw()
print(c.calculator())
# 원형
# 28.274328