Python TIL(7) - Class

random·2021년 4월 5일
0

Python - TIL

목록 보기
7/19

Class, inheritance and polymorphism

클래스의 상속과 다형성에 대해 탐구해보기. 입출금이 가능한 은행계좌 프로그램 설계해보기.


#class inheritance

class Animal():

    def __init__(self):
        print("ANIMAL CREATED")

    def who_am_i(self):
        print("I am an animal")

    def eat(self):
        print("I am eating")
  • <init> method: initialize method(초기화 메서드)를 말한다. class를 생성했을때 초기화를 시켜주는 특수한 메서드이다. 메서드는 일반함수와의 구분을 위한것으로 클래스의 함수를 메소드라고 부름. 파이썬에는 여러 형태의 메소드가 있는데 여기서 칭하는 특정 함수 내 메소드와 여타 메소드를 구분해야함.

  • <init> method의 가장 처음으로 호출되어야 되는 첫번째 인자는 self이다. 다른 인자명을 적어도 작동은 하나 파이썬에서는 Self로 통일하는 것이 오랜 관습임.


class Dog(Animal):  
   
   def __init__(self):
       Animal.__init__(self)
       print("Dog Created")

   def who_am_i(self):
       print("I am a dog!")

   def mydog_bark(self):
       print("Whoof!")

mydog = Dog()
mydog.eat() 
mydog.who_am_i()
mydog.mydog_bark()
  • 본 Class Dog() 소괄호 안에 위 Animal 클래스를 적어넣음으로써 해당 클래스 성질을 상속 받는 것을 의미함.
  • mydog.eat() 표현에서 print 출력은 생략해도됨. 그 까닭은 이미 eat() 어트리뷰트 메소드에 기적용되어있는 명령이라 해당함수 호출을 하면 print가 자동을 됨.
  • 위 인스턴스 클래스 (아들 클래스)는 상위 클래스 (어머니 클래스)의 내용중 원하는 부분에 한해서 Overriding 할 수 있음.
  • def who_am_i(self):
    print("I am a dog!")
    위 부분을 통해서 원래 "I am an animal"이었던 출력물이 "I am a dog"로 변경됨.

#polymorphism

class Wolf():

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

    def speak(self):
        return self.name + " says Ahoo!~"

class Cat():

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

    def speak(self):
        return self.name + " says Meow!~"

lulu = Wolf("lulu")
nabi = Cat("nabi")

print(lulu.speak())
print(nabi.speak())

for pet in [lulu, nabi]:
    print(type(pet))
    print(type(pet.speak))

def pet_speak(pet):
    print(pet.speak())

pet_speak(nabi)
  • 위 내용은 다형성(Polymorphism)을 활용한 간단한 소스코드 예시임.
  • Wolf, Cat 클래스 둘 다 speak라는 메소드를 품고 있음.
  • for pet in [lulu, nabi]:,type(pet) 명령을 통해서 각기 다른 클래스에 속한 타입임이 확인됨.
    <class 'main.Wolf'>
    <class 'main.Cat'>
  • 다형성은 같은 모양의 코드가(위 예시에서는 Speak 메소드) 다른 객체로서 다른 클래스의 동작을 하는 기능을 의미함.


#abstract class

class Animal2():   

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

    def speak(self):
        raise NotImplementedError("Subclass must implement this abstract method")

class Wolf2(Animal2):

    def speak(self):
        return self.name + " says Ahoo!~"

class Cat2(Animal2):

    def speak(self):
        return self.name + " says Meow!~"

jack = Wolf2("Jack")
isis = Cat2("Isis")
print(jack.speak())
print(isis.speak())
  • 실제로, abstract class와 inheritance를 쓰는게 Polymorphism 보다 더 자주 활용된다.
  • "abstract classs"는 실제로 클래스로서 독자적으로 하는 일은 없고, 그저 상속받고 오버라이딩을 위한 기능을 하는 플랫폼적 역할만 함!
  • raise NotImplementedError를 선언해야지만(이 abstract 메소드를 실행해야지만), derived classes(아들 클래스)가 상위 class 메소드(어머니 클래스)를 오버라이딩 할 수 있음.
    *raise Not ImplementedError의 다른 용법으로는 다른 개발자들 혹은 나중에 이 소스코드를 볼 나 자신에게 이 부분은 추가/보완해야될 부분이 있다고 암시하는 기법임. pass를 쓰고 넘어가면 내부 소스코드를 직접 찾아보지 않는 이상 영영 못발견하고 넘어갈 수도 있음.
  • 결론적으로 "jack.speak()", "isis.speak()" 를 실행해보면, 아무런 에러 없이, Animal2 클래스를 상속받은 Wolf2, Cat2의 Speak가 실행되게 된다.

class Account():

    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance


    def deposit(self, damount):
        self.balance = self.balance + damount
        print("Hello, {}. We added '{}' to the balance, and the current balance is '{}'".format(self.owner, damount, self.balance))

        #여기서 print 대신 return은 못 쓰는 걸까?

    def withdraw(self, wamount):
        if self.balance >= wamount:
            self.balance = self.balance - wamount  #여기서 시작을 self-balance로 안해주면 추후 남은 잔고가 반영이 안됨.
            print("Hello, {}. We subtracted '{}' to the balance, and the current balance is '{}'".format(self.owner, wamount, self.balance))

        elif self.balance < wamount:
            self.balance = -(self.balance - wamount)
            print(f"Sorry, that exceeds your withdrawl limit for '{self.balance}'")

acct1 = Account(owner = 'Jose', balance = 100)
acct1.deposit(50)
acct1.withdraw(100)
acct1.withdraw(30)
acct1.withdraw(2000)
  • 상속 개념을 이용한 은행 입출금 계좌 예제.
  • 현재 잔고에서 입금, 출금이 가능하게 설계 되었고, 잔고가 부족할 시 한도초과 메세지를 보내줌.

0개의 댓글