본문 바로가기

카테고리 없음

6일차 - 2

상속

파이썬에서 상속은  클래스의 속성과 메서드를 다른 클래스에 전달하는 기능을 의미합니다. 상속을 사용하면 기존의 코드를 재사용하고 확장할  있습니다. 기본적으로 파이썬의 모든 클래스는 object라는 기본 클래스로부터 상속받습니다.

class parent:
    pass
class child(parent):
    pass
class Animal:        # 클래스 첫 이름은 관례적으로 대문자로 많이 쓴다
  def __init__(self,name,age):
      self.name = name
      self.age = age

  def eat(self, food):
    print(f'{self.name}은(는) {food}를 먹습니다.')

  def sleep(self,hour):
    print(f'{self.name}은(는) {hour}시간 동안 잠을 잡니다')
animal = Animal( '동물', 10)
animal.eat('먹이')
animal.sleep(10)
동물은(는) 먹이를 먹습니다.
동물은(는) 10시간 동안 잠을 잡니다
class Dog(Animal): # 애니멀 클래스의 모든걸 사용가능
  pass
# Rucy = Dog() # 애니멀 클래스를 상속받았기 때문에 애니멀 클래스의 생성자 매개변수를 전달해줘야 함.
Rucy = Dog('루시', 14)
Rucy.eat('사료')
Rucy.sleep(10)
루시은(는) 사료를 먹습니다.
루시은(는) 10시간 동안 잠을 잡니다

 

클래스 상속 시 생성자 호출 순서

1. 자식 클래스(child class)의 생성자가 호출됩니다.
2. 자식 클래스의 생성자에서 부모 클래스(parent class)의 생성자를 호출해야 합니다. 이를 위해 super() 함수를 사용합니다. super() 함수는 현재 클래스의 부모 클래스를 참조하며, 부모 클래스의 생성자를 호출할 수 있습니다.
3. 부모 클래스의 생성자가 호출됩니다.
4. 부모 클래스의 생성자가 실행을 마치면 자식 클래스의 생성자로 돌아가 자식 클래스의 생성자 코드가 실행됩니다.

class Parent:
  def __init__(self):
    print('부모 클래스 생성자 호출')

class Child(Parent):
  def __init__(self):
    print('Child 클래스 생성자 호출')
    super().__init__()
    print('자식 클래스 생성자 호출')
child = Child()
Child 클래스 생성자 호출
부모 클래스 생성자 호출
자식 클래스 생성자 호출

 

Object 클래스

object는 파이썬의 모든 클래스의 기본 클래스입니다. object 클래스는 파이썬에서 모든 객체의 기본적인 동작과 특성을 정의합니다. 

 

class Myclass:
    pass
class Myclass(object):
    pass

 

메서드 오버라이딩

 

메서드 오버라이딩(Method Overriding)은 객체 지향 프로그래밍에서 중요한 개념  하나로, 서브 클래스(자식 클래스)에서 슈퍼 클래스(부모 클래스)의 메서드를 재정의하는 것을 의미합니다. 오버라이딩을 사용하면, 서브 클래스에서 상속받은 메서드의 동작을 변경하거나 확장할  있습니다.

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

  def eat(self, food):
    print(f'{self.name}은(는) {food}를 먹습니다.')

  def sleep(self,hour):
    print(f'{self.name}은(는) {hour}시간 동안 잠을 잡니다')
class Dog(Animal):
  def run(self):
    print(f'{self.name}은(는) 달립니다')
Rucy = Dog('루시', 14)
Rucy.eat('사료')
Rucy.run()
루시은(는) 사료를 먹습니다.
루시은(는) 달립니다
class Animal:
  def __init__(self,name,age):
      self.name = name
      self.age = age

  def eat(self, food):
    print(f'{self.name}은(는) {food}를 먹습니다.')

  def sleep(self,hour):
    print(f'{self.name}은(는) {hour}시간 동안 잠을 잡니다')
class Dog(Animal):
  def run(self):
    print(f'{self.name}은(는) 달립니다')

  def eat(self, food):
    print(f'{self.name}은(는) {food}를 아주~ 맛있게 먹습니다.')

  def superEat(self, food):
    super().eat(food)
Rucy = Dog('루시', 14)
Rucy.eat('사료')
루시은(는) 사료를 아주~ 맛있게 먹습니다.
Rucy.superEat('사료')
루시은(는) 사료를 먹습니다.​

마지막 코드에 super구문을 썻으니 부모 클래스에 있는 eat구문을 쓴다.

다중 상속

다중 상속은 클래스가  이상의 부모 클래스로부터 상속을 받는 기능을 의미합니다. 파이썬은 다른 많은 객체 지향 언어와 달리 다중 상속을 지원합니다. 다중 상속을 사용하면 코드의 재사용성을 향상시킬  있지만, 동시에 복잡성이 높아지기 때문에 주의해야 합니다.

class Parent1:
    pass
class Parent2:
    pass
class Child(Parent1, Parent2)
    pass
class Animal:
  def __init__(self,name,age):
      self.name = name
      self.age = age

  def eat(self, food):
    print(f'{self.name}은(는) {food}를 먹습니다.')

  def sleep(self,hour):
    print(f'{self.name}은(는) {hour}시간 동안 잠을 잡니다')
class Human :
  def __init__(self,name,age):
    self.name =name
    self.age = age

  def study(self,hour):
    print(f'{self.name}은(는) {hour}시간 동안 공부를 합니다')
  def sleep(self,hour):
    print(f'{self.name}은(는) {hour}시간 동안 꿀잠을 잡니다')
class Kimapple(Animal, Human):
  pass
kim = Kimapple('김사과', 20)
kim.eat('밥')
kim.study(2)
kim.sleep(8)
김사과은(는) 밥를 먹습니다.
김사과은(는) 2시간 동안 공부를 합니다
김사과은(는) 8시간 동안 잠을 잡니다

 

c3 선형화 알고리즘

파이썬의 다중 상속에서 메서드 해결순서를 계산하는데 사용되는 알고리즘

복잡한 상속 구조에서 메서드 호출 순서를 명확하게 결정하기 위해 고안된 알고리즘

 

super() 메소드

 

super()는 파이썬의 내장 함수로서, 상속과 관련된 작업을 수행할  사용됩니다. 특히, 자식 클래스에서 부모 클래스의 메서드를 호출할  사용됩니다. super()의 주요 목적은 자식 클래스에서 부모 클래스의 메서드를 오버라이드(재정의)하면서도  오버라이드된 메서드 내에서 부모 클래스의 원본 메서드를 호출하는 것입니다.

 

class Parent:
  def hello(self):
    print('부모클래스의 hello 메서드')

class Child(Parent):
  def hello(self):
    super().hello()
    print('자식 클래스의 hello 메서드')
child = Child()
child.hello()
부모클래스의 hello 메서드
자식 클래스의 hello 메서드
class Parent:
  def __init__(self, value):
    self.value =value
class Child(Parent):
  def __init__(self, value,child_value):
    super().__init__(value) # 부모의 생성자를 호출해야 함
    self.child_value=child_value
child = Child(10,20)
print(child.child_value)
print(child.value)
20
10
class Base:
  def hello(self):
    print('Base 클래스의 hello 메서드')
class A(Base):
  def hello(self):
    super().hello()
    print('A클래스의 hello 메서드')
class B(Base):
   def hello(self):
    super().hello()
    print('B클래스의 hello 메서드')
class Child (A,B):
   def hello(self):
    super().hello()
    print('Child클래스의 hello 메서드')
Child.mro()
[__main__.Child, __main__.A, __main__.B, __main__.Base, object]

메서드 해석 순서 (Method Resolution Order, MRO):

파이썬에서는 위와 같은 다이아몬드 문제를 해결하기 위해 MRO를 사용합니다. MRO는 클래스의 메서드를 찾을 때 사용하는 규칙입니다.

D 클래스의 경우 MRO [D, B, C, A] 결정됩니다. 따라서 d.hello() 호출하면 B 클래스의 hello() 메서드가 실행됩니다.