파이썬과 객체지향 프로그래밍 - 예제로 이해하는 객체지향 문법 (public, private, protected)

5. 예제로 이해하는 객체지향 문법 (public, private, protected)

private, protected, public

  • 정보 은닉(Information Hiding) 방식
    • class의 attribute, method 에 대해 접근을 제어할 수 있는 기능

  • private -> protected -> public
    • private: private로 선언된 attribute, method는 해당 클래스에서만 접근 가능
    • protected: protected로 선언된 attribute, method는 해당 클래스 또는 해당 클래스를 상속받은 클래스에서만 접근 가능
    • public: public으로 선언된 attribute, method는 어떤 클래스라도 접근 가능

파이썬에서의 private, protected, public

  • java, C++언어 등의 객체지향 언어와 달리, 파이썬에서의 모든 attribute, method는 기본적으로 public
  • 즉, 클래스 외부에서 attribute, method 접근 가능 (사용 가능)
In [69]:
class Quadrangle:
    def __init__(self, width, height, color):
        self.width = width
        self.height = height
        self.color = color

    def get_area(self):
        return self.width * self.height
    
    def set_area(self, width, height):
        self.width = width 
        self.height = height
In [ ]:
 
In [70]:
square = Quadrangle(5, 5, "black")
print(square.get_area())
print(square.width)
square.width = 10
print(square.get_area())
25
5
50


In [71]:
dir (square)
Out[71]:
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'color',
 'get_area',
 'height',
 'set_area',
 'width']

protected

  • 파이썬에서는 해당 속성의 앞에 _(single underscore) 를 붙여서 표시만
  • 실제 제약되지는 않고 일종의 경고 표시로 사용됨
In [61]:
class Quadrangle:
    def __init__(self, width, height, color):
        self._width = width
        self._height = height
        self._color = color

    def get_area(self):
        return self._width * self._height
    
    def _set_area(self, width, height):
        self._width = width 
        self._height = height
In [62]:
square = Quadrangle(5, 5, "black")
print(square.get_area())
print(square._width)
square._width = 10
print(square.get_area())
square._set_area(3, 3)
print(square.get_area())
25
5
50
9

private

- 파이썬에서는 attribute, method 앞에 __(double underscore)를 붙이면 실제로 해당 이름으로 접근이 허용되지 않음
- 실은 __(double underscore)를 붙이면, 해당 이름이 _classname__해당 속성 또는 메소드 이름 으로 변경되기 때문임
In [73]:
class Quadrangle:
    def __init__(self, width, height, color):
        self.__width = width
        self.__height = height
        self.__color = color

    def get_area(self):
        return self.__width * self.__height
    
    def __set_area(self, width, height):
        self.__width = width 
        self.__height = height
In [74]:
square = Quadrangle(5, 5, "black")


In [75]:
dir(square)
Out[75]:
['_Quadrangle__color',
 '_Quadrangle__height',
 '_Quadrangle__set_area',
 '_Quadrangle__width',
 '__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'get_area']
  • dir(square) 로 다음 이름 확인 가능
    '_Quadrangle__color',
    '_Quadrangle__height',
    '_Quadrangle__set_area',
    '_Quadrangle__width'
    
In [76]:
square = Quadrangle(5, 5, "black")
print(square.__set_area(10, 10))
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-76-884d04e59221> in <module>()
      1 square = Quadrangle(5, 5, "black")
----> 2 print(square.__set_area(10, 10))

AttributeError: 'Quadrangle' object has no attribute '__set_area'
In [77]:
print(square.__width)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-77-a6b5c49439a6> in <module>()
----> 1 print(square.__width)

AttributeError: 'Quadrangle' object has no attribute '__width'
In [78]:
print(square.get_area())
25

초간단 연습4

  • 위 클래스, 객체를 기반으로 다음 코드 실행해보고 안되는 이유 생각해보기
    print(square.__width)
    square.__width = 10
    square.__set_area(3, 3)
    
In [79]:
print(square.__width)
square.__width = 10
square.__set_area(3, 3)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-79-ff8edbc0e5fc> in <module>()
----> 1 print(square.__width)
      2 square.__width = 10
      3 square.__set_area(3, 3)

AttributeError: 'Quadrangle' object has no attribute '__width'


한발짝 더 나가보기!(심화 문제)
* 원 클래스를 만들기
- attribute: 원 반지름, 원 이름
- method:
1. 원 이름 리턴 메서드
2. 원 넓이 리턴 메서드
- 참고(원 넓이 식): 3.14 X 원 반지름 ** 2(원 반지름의 제곱)
3. 원 길이 리턴 메서드
- 참고(원 길이 식): 2 X 3.14 X 원 반지름
- 생성자에서만 attribute 값 설정 가능
- attribute는 private 으로 설정
In [90]:
class Circle:
    def __init__(self, radius, name):
        self.__radius = radius
        self.__name = name

    def get_name(self):
        return self.__name
    
    def get_area(self):
        return 3.14 * self.__radius ** 2
    
In [91]:
circle = Circle(3, 'dave')
print (circle.get_name(), circle.get_area())
dave 28.26
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [34]:
class Circle:
    def __init__(self, radius, name):
        self.__radius = radius
        self.__name = name

    def get_name(self):
        return self.__name

    def get_area(self):
        return 3.14 * self.__radius ** 2

    def get_length(self):
        return 2 * 3.14 * self.__radius

circle = Circle(3, 'dave')
print (circle.get_name(), circle.get_area(), circle.get_length())
dave 28.26 18.84


과제
1. 계좌 관리 class 작성하기
- attribute: 계좌 초기 금액을 속성으로 하나 설정
- 생성자에서 초기 금액은 0으로 설정
- 속성은 private 으로 설정
- method: 인출, 저축, 잔액 확인 세 가지 method 구현, 각각 현재 계좌 금액 리턴
- 각 method 도 private 으로 설정

2. 학생 성적 관리 class 작성하기
- attribute: 국어, 영어, 수학, 학생 이름 네 개의 속성
- 생성자에서 각 속성을 객체 생성시 전달된 인자값으로 설정
- 각 속성은 private 으로 설정
- method: 전체 과목 점수 평균, 전체 과목 총점 두 가지 method 구현
- 각 method 는 private 으로 설정

3. 피자 가게 관리 class 작성하기
- attribute: 피자 종류(리스트 데이터 타입), 피자 가게 이름 속성
- 생성자에서 각 속성을 객체 생성시 전달된 인자값으로 설정, 피자 종류는 ['슈퍼슈프림', '콤비네이션', '불고기']로 제공
- 각 속성은 private 으로 설정
- method: 원하는 피자를 제공하는지를 알려주는 기능, YES 또는 NO 문자열을 리턴
In [ ]: