CS

파이썬 - 객체지향 프로그래밍

빛날희- 2022. 8. 25. 10:12
🤖

인프런의 파이썬 강의를 수강한 후 정리한 내용입니다.


  • 객체지향 프로그램이란? Object Oriented Programming 속성과 기능을 포함한 프로그램 단위로, 프로그램의 구성요소를 객체화 하는 것을 말한다.

  • 클래스란? 객체를 생성하기 위한 틀로, 하나의 클래스로부터 여러개의 객체를 생성할 수 있다.

# class01.py
class Calculator:
    def __init__(self):
        self.result = 0

    def add(self, num):
        self.result += num
        return self.result

		def sub(self, num):
		        self.result -= num
		        return self.result

→ Calculator라는 클래스에는 숫자를 더하는 add기능과 빼는 sub기능이 있다. __init__생성자에서 객체의 속성을 정의해준다.

  • 주의할 점❗ 클래스로부터 객체를 생성했을 때 생성한 객체들은 메모리에 탑재될 때 전혀 다른 곳에 부여되기 때문에 별개의 객체라는 것을 알아야한다.
    cal1= Calculator()
    cal2= Calculator()
    
    print(cal1.result)
    print(cal2.result)
    
    cal2.result=1
    print(cal1.result)
    print(cal2.result)

    위 코드를 실행했을 때의 결과이다. cal1cal2 는 같은 클래스로부터 생성되었지만 다른 객체이므로 속성을 바꾸었을 때 다른 객체에 영향을 주지 않는 것을 볼 수 있다.

  • 접근자란? 외부에서 객체의 속성과 기능에 대한 접근을 제한할 수 있다.
    • public: 외부에서 접근 가능
    • private: 외부에서 접근 불가능, 속성은 함수 내에서만 쓰일 수 있는 경우 ex) 회사 인재 시스템에서 A직원의 급여 속성은 외부에서 접근할 수 없어야 함
    • private 네이밍 규칙: 변수명 앞에 __ 사용, 변수명 뒤에 쓴다면 _ 붙여서 사용

    # class02.py
    class pay:
        def __init__(self):
            self.day=20
            self.__money= 100
        
        def getmoney(self):
            return self.__money
        
        def changemoney(self, money):
            self.__money = money
            return self.__money

    위 클래스를 만들고 아래 코드를 실행하면 다음과 같은 결과가 나온다.

    lsh= pay()
    print(lsh.__money)

    pay객체에서 private 속성인 __money 에 접근할 수 없기 때문에 에러가 발생했다.

    해당 속성에 접근하기 위해선 정의한 getmoney기능을 사용할 수 있다. 또한 changemoney기능을 통해 해당 속성값을 변경할 수 있다.

    print(lsh.day)
    print(lsh.getmoney())
    
    lsh.changemoney(200)
    print(lsh.getmoney())

  • self란? 객체 자신을 가리킨다. 클래스로부터 객체가 메모리에 생성될 때, 인터프리터가 객체를 호출하게 된다. 이 때 인터프리터가 self를 메소드에 던져주기 때문에 사용자는 self에 대해 따로 파라미터로 넣어줄 필요가 없다.

  • 객체 생성 매세드와 초기화 메서드 __name__ 메서드에선 메모리에 생성된 객체를 탑재해주는 역할을 한다. __init__ 메서드에선 객체 초기화를 담당한다. 클래스 메서드는 객체 생성 전에 클래스 내에서 생성된 메서드이고, 인스턴스 메서드__init__ 에서 생성된 메서드를 의미한다. 따라서 인스턴스 메서드는 self의 속성으로 접근 가능해야 하고, 클래스 메서드는 클래스 내에서 생성된 메서드이기 때문에 모든 객체에서 공유된다.
    # class03.py
    class student:
        double_major= [] # 클래스 메서드
    
        def __init__(self, name):
            self.name= name
    				# self.double_major = [...]
    
        def printInfo(self):
            print(self.name)
            print(self.double_major)
        
        def setDoubleMajor(self, doubleMajor):
            self.double_major.append(doubleMajor)

    double_major__init__ 앞에 선언함으로써 클래스 메서드로 만든다.

    lsh= student('seoh2')
    lsh.setDoubleMajor('english')
    lsh.printInfo()
    
    lsh2= student('lsh2')
    lsh2.setDoubleMajor('korean')
    lsh2.printInfo()

    lshlsh2 는 따로 생성된 객체이지만 double_major 는 모든 객체가 공유하는 메서드이기 때문에 추가된 값이 누적되었음을 알 수 있다.

  • 정적 메서드와 클래스 메서드
    • 정적 메서드 @staticmethod: 객체를 생성하지 않고 객체에 바로 접근할 수 있도록 함
      # class09.py
      class Static:
      
          @staticmethod
          def printMethod():
              print('use static method')
      
      # ---
      Static.printMethod()
    • 클래스 메서드 @classmethod : 매개변수로 cls를 항상 넣어야 한다. 클래스의 속성(class03.py코드에 있는 double_major )에 접근하여 해당 속성을 사용할 수 있도록 한다.

  • 상속 부모클래스의 속성과 기능을 자식 클래스에서 사용가능하다.
    • 부모클래스의 public값만 가지고 올 수 있다.
    • 부모클래스의 __init__ 메소드의 속성을 가지고 올 수 없으므로, 부모클래스의 속성을 사용하고 싶다면 자식클래스의 생성자에서 강제로 호출해줘야한다.
      # class04.py
      class Parent:
          def __init__(self):
              self.what= 0
      
          def printMethod(self):
              print('helloooo')
      
      class Child(Parent):
          def __init__(self):
              pass
      
      # ---
      c= Child()
      c.printMethod()
      print(c.what)

      볼 수 있다싶이, 자식클래스에서 기능은 상속받을 수 있지만 부모클래스의 속성인 what은 상속받지 못해 에러가 난다.

      따라서 다음과 같이 자식클래스의 생성자에서 부모클래스의 생성자를 호출해줘야한다!

      class Parent:
          def __init__(self):
              self.what= 0
      
          def printMethod(self):
              print('helloooo')
      
      class Child(Parent):
          def __init__(self):
              Parent.__init__(self)
              pass

  • 오버라이딩 부모 클래스의 기능을 자식 클래스에서 재정의할 수 있다.
    # class05.py
    class Parent:
        def __init__(self):
            self.what= 0
    
        def printMethod(self):
            print('helloooo')
    
    class Child(Parent):
        def __init__(self):
            Parent.__init__(self)
        
        def printMethod(self):
            print('hello child')
    
    # ---
    c= Child()
    c.printMethod()

    printMethod가 부모클래스에선 ‘helloooo’를 출력하는 기능이었지만, 자식클래스에서 ‘hello child’를 출력하도록 기능을 재정의했다.

  • 다중상속 자식 클래스에서 2개 이상의 부모 클래스를 상속할 수 있다.
    • 다중 상속을 하다보면 중복되는 메서드가 생길 수 있다. 따라서 하나의 부모 클래스만 상속하거나 다중상속을 한다면 중복 메서드가 없도록 잘 관리해야한다.
    # class06.py
    class parent1:
        def __init__(self):
            pass
        def method1(self):
            print('parent method1')
    
    class parent2:
        def __init__(self):
            pass
        def method2(self):
            print('parent method2')
    
    class parent3:
        def __init__(self):
            pass
        def method3(self):
            print('parent method3')
    
    class child(parent1, parent2, parent3):
        def __init__(self):
            pass
    
    # ---
    c= child()
    c.method1()
    c.method2()
    c.method3()

  • 추상클래스 자식클래스에서 반드시 다시 재정의(구현)해야하는 부모 클래스이다.
    • 추상클래스를 구현하기 위해선 다음 패키지를 불러와야한다.
    • 자식클래스에서 추상클래스를 구현하지 않으면 다음과 같은 에러가 난다.
    # class07.py
    from abc import ABCMeta, abstractmethod
    
    class Parent(metaclass= ABCMeta):
        def __init__(self):
            self.what= 0
        
        @abstractmethod
        def printMethod(self):
            print('helloooo')
    
    class Child(Parent):
        def __init__(self):
            Parent.__init__(self)
        
        # def printMethod(self):
        #     print('hello child')
    
    # ---
    c= Child()
    c.printMethod()

  • super() 부모 클래스의 객체를 가리킨다.
    • 상속을 받을 때 자식클래스에서 부모클래스의 속성은 사용할 수 없으므로, 자식클래스의 생성자에서 부모클래스의 생성자를 강제로 호출함으로써 사용한다.
    • 위 방법 대신, 생성자에 super()를 사용함으로써 자식클래스의 상위 클래스인 부모클래스에서 속성을 받아 사용할 수 있다.
    • self는 파라미터로 넣어주지 않아도 된다.
    # class08.py
    class Parent:
        def __init__(self):
            self.what= 0
    
        def printMethod(self):
            print('helloooo')
    
    class Child(Parent):
        def __init__(self):
            super().__init__()
        
        def printMethod(self):
            print('hello child')
    
    # ---
    c= Child()
    c.printMethod()
    print(c.what)


Uploaded by N2T

'CS' 카테고리의 다른 글

네트워크 프로토콜  (0) 2022.08.30
파이썬 - 자료구조와 동작원리  (0) 2022.08.18