class

  • OOP 설계

    • 계좌 만들기 예제를 통해 구현
    • class 모습을 살펴보자.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
         # 전역 함수 : 어느 클래스에도 속하지 않는다.
      # OOP 설계에서는 쓰지 않는 방법이기 때문에 staticmethod 개념 존재
      def func(a, b):
      return a + b


      class Account:
      # 클래스 이름의 맨 앞은 대문자로 하도록 하자.
      # 클래스 멤버(class member)
      # 모든 객체가 공유한다.
      # 전역 변수(global variable)를 대체
      # ex) 이자율
      interest_rate = 0.08
      num_of_account = 0


      # 클래스 메소드(class method)
      # 객체가 하나도 없는 상태에서도 호출이 가능!!
      # 전역 함수(global variable)를 대체
      # 전역 함수를 대체할 때는 static method를 쓸 수도 있다.
      # 대체 생성자(alternative constructor)
      # cls는 클래스 자체를 받는다.

      # staticmethod는 메소드처럼 보이지만 함수 : 전역 함수
      @staticmethod
      def func(a, b):
      return a + b

      @classmethod #데코레이터
      def get_num_of_account(cls):
      """
      Account.get_num_of_account() -> integer
      """
      return cls.num_of_account


      # 대체 생성자
      # 받을 데이터에 맞춰서 설계
      @classmethod
      def string_constructor(cls, string):
      data = string.split('_')
      clnt_name = data[0]
      balance = int(data[1])
      return cls(clnt_name, balance)


      # 생성자(constructor) : 파이썬에서는 오직 하나
      # 객체(object)가 생성될 때 반드시!!! 한번 호출된다.
      def __init__(self, clnt_name, balance):
      # 인스턴스 멤버(instance member) --> 상태 정보 = 데이터
      # self라는 말은 자기 스스로의 메모리를 가리킨다는 의미
      # self는 객체 메모리를 자체 참조
      self.clnt_name = clnt_name

      # 변수 앞에 "__"를 붙이면 정보 은닉으로 접근하지 말라는 표시
      # 변환 규칙 중에 "_현재클래스이름__멤버변수"를 하면 접근 가능
      self.__balance = balance

      # 클래스 멤버에 접근하는 방법
      Account.num_of_account += 1

      # 인스턴스 메소드(instance method)
      def deposit(self, money):
      """
      deposit(money) --> boolean
      만약에 money > 0이면 입금 성공!
      아니면 에러 메시지 출력 후 실패!
      """
      if money < 0:
      print("입금은 0원 초과부터 가능합니다.")
      return False
      else:
      self.__balance += money
      print(f'{money}원을 입금하셨고, 현재 남아있는 금액은 {self.__balance}원입니다.')
      return True

      # 인스턴스 메소드
      def withdraw(self, money):
      """
      withdraw(money) --> integer
      return : 인출된 돈
      만약 잔고가 모자라면 None
      """
      if self.__balance < money:
      print(f'현재 금액은 {self.__balance}원으로, 출금하실 금액 {money}원보다 부족하여 출금하실 수 없습니다.')
      return None
      else:
      self.__balance -= money
      print(f'{money}원을 출금하였고, 현재 남아있는 금액은 {self.__balance}원입니다.')
      return money

      def transfer(self, other, money):
      # 내 객체가 가진돈
      self.__balance -= money
      # message passing
      # 다른 객체의 상태 정보(인스턴스 멤버)를 변경할 대는 반드시 상대 객체가
      # 가진 메소드를 이용
      # 절대 상대의 객체에 직접 접근하면 안된다.
      other.deposit(money)

      def __str__(self):
      return f'{self.clnt_name} : {self.__balance}'


      if __name__ == '__main__':

      # 객체가 생성되지 않아도 호출이 가능
      print(Account.interest_rate)
      >> 0.08
      print(Account.get_num_of_account())
      >> 0

      # 객체를 생성
      my_acnt = Account('greg', 5000)
      your_acnt = Account('john', 2000)
      print(my_acnt.interest_rate)
      >> 0.08

      print(my_acnt.get_num_of_account())
      >> 2

      print(Account.func(5, 4))
      >> 9

      print(type(Account.func))
      >> <class 'function'>

      print(type(Account.get_num_of_account))
      >> <class 'method'>

      print(type(my_acnt.deposit))
      >> <class 'method'>


      # 대체 생성자를 이용한 객체의 생성
      s = 'james_6000'
      his_acnt = Account.string_constructor(s)
      print(his_acnt)
      >> james : 6000

      # instance method 호출하는 방법
      # 외부에서는 self는 자동으로 들어가기 때문에 매개 변수에 쓸 필요가 없다.
      my_acnt.deposit(7000)
      >> 7000원을 입금하셨고, 현재 남아있는 금액은 12000원입니다.

      # 메소드 vs 함수(일반)
      # 메소드 = 입력 + 인스턴스 멤버(상태 정보, 데이터)에 의해 결과값이 결정!
      # = 인스턴스 멤버(상태 정보)를 바꾸는 역할!
      # 함수 = 입력에 의해서 출력이 결정
      res1 = my_acnt.withdraw(3000)
      >> 3000원을 출금하였고, 현재 남아있는 금액은 9000원입니다.
      res2 = your_acnt.withdraw(3000)
      >> 현재 금액은 2000원으로, 출금하실 금액 3000원보다 부족하여 출금하실 수 없습니다.
      print(my_acnt)
      >> greg : 9000
      print(your_acnt)
      >> john : 2000


      # 객체 간에 상호 작용 --> 객체가 가지고 있는 멤버 값(데이터, 상태정보)
      # INTERACTRION by 메소드에 의해!!
      # my_acnt.transfer(your_acnt, 1000)
      my_acnt.transfer(your_acnt, 1000)
      >> 1000원을 입금하셨고, 현재 남아있는 금액은 3000원입니다.

      # 절대 짜서는 안되는 코드
      # 이렇게 멤버 변수에 직접 접근하는 방법은 좋지 않다.
      # my_acnt.balance -= 1000
      # your_acnt.balance += 1000
Share