객체지향프로그래밍이란 6편 -다형성,캡슐화-

1. 다형성(polymorphism)

 

여러 모양을 뜻하는 그리스어

 

동일한 메소드가 클래스에 따라 다르게 행동할 수 있다

 

서로 다른 클래스에 속해있는 객체들이 동일한 메시지에 대해 다른 방식으로 응답가능

 

부모에 talk()가 있고 자식에 talk()가 있을때, talk()를 사용하면, 어떤 talk()를 사용하게 되는가?

 

자식에서 talk()를 먼저 찾아봐서 있으면 자식의 talk()를 쓰고, 그렇지 않으면 부모에서 talk()를 찾아 부모 talk()를 쓰게 되는

 

 

2. method overriding(덮어쓰기)

 

클래스를 상속할 때, 부모 클래스에서 정의한 메소드를 자식 클래스에서 재정의하는 것

 

부모 클래스의 메소드 이름과 기본 기능은 그대로 사용하더라도 특정 기능을 재정의해서 바꾸고 싶을 때

 

예시) Person을 상속받은 3가지 class Man, Professor, Student

 

 

__init__ method를 정의하지 않은 Professor()에서 그냥 생성하면 자식에게 __init__이 없기때문에 부모의 __init__을 찾아서 name을 내놓으라고 하는데

 

__init__을 정의한 Man에서는 부모의 __init__을 물려받았을테니까

 

부모의 __init__과 자식의 __init__을 모두 써볼려고 name,age를 주면 역시 에러가 난다.

 

왜냐하면 자식의 __init__으로 재정의되었기때문에 age만 줘야함

 

 

Man은 talk()를 물려받은것은 맞는데, name이 없으므로 name을 정의해줘야 물려받은 talk()를 사용가능

 

 

 

Professor()은 talk()를 가지고 있어서 p.talk()하면 부모의 talk()를 쓰지 않고 새로 재정의한 Professor()의 talk()로 동작

 

 

완전히 재정의하는 것이 아닌 부모의 기능을 일부 가지고 새로운 기능을 추가할 수도 있다.

 

Student()에서는 super().talk()로 부모의 talk()기능을 가져오고, 거기에 print(f'저는 학생입니다.')라는 새로운 기능을 추가해서 재정의했다

 

 

3. 캡슐화

 

객체의 일부 구현 내용에 대해 외부로부터의 직접적인 접근을 차단하는 것

 

예를 들어 주민등록번호같은 중요 내용을 변경하는 것을 막기 위함

 

 

캡슐처럼 안의 내용을 안보이게 막는 느낌?

 

캡슐을 먹으면서 내용물을 쓰는 것처럼 사용은 가능한데 캡슐을 뜯어서 내용물을 수정해가지고 먹는다거나 그러지는 않잖아

 

'파이썬에서는 암묵적으로 존재하지만, 언어적으로 존재하지는 않는다'

 

==공식적으로는 존재하지 않는다

 

 

4. 접근제어자

 

public access modifier, protected access modifier, private access modifier

 

전부 접근 가능하고, 일부만 접근 가능하고, 극히 일부만 접근 가능하고

 

 

4-1) public member

 

일반적으로 작성하는 메소드, 속성의 대다수로

 

언더바(_)없이 시작하는 메소드나 속성을 의미함

 

이름도 고칠 수 있고 어디서나 호출,접근이 가능하고 하위 클래스의 override를 허용함

 

 

 

4-2) protected member

 

언더바(_) 1개로 시작하는 메소드나 속성을 의미하고

 

암묵적인 규칙으로 부모클래스 내부와 자식 클래스에서만 호출 가능함

 

하위 클래스의 override는 허용함

 

외부에서는 접근하지 말자고 파이썬 문화적으로 약속하는 것

 

만약에 접근할려면 다른 메소드를 이용해서 접근하는 것이 일반적임

 

 

self._age = age로 만들면 일반적인 p1.age로는 접근이 불가능하지만

 

 

get_age() 메소드를 활용해서 age 값을 접근하거나, 이런 경우는 원래의 변수명 age를 get_age로 약간 숨겨주는 느낌?

 

실제로 p1._age로 직접 접근이 가능하지만, 암묵적으로 활용하진 않는다

 

get_information()같은 식으로 메소드를 활용해서 직접적인 접근은 하지말았으면 좋았을때 사용

 

직접적으로 변경하는 것보다 setter method를 활용해서 변경해가지고, 데이터가 변경되면 알림이 뜨도록 만들고 싶을 때

 

데이터를 변경하면 기타 다른 처리(알림, 다른 데이터도 변경 등등)가 수반되도록 하고싶을때

 

 

4-3) private member

 

언더바 2개(__)로 시작하는 메소드나 속성

 

진짜로 상당 부분을 막는거임 이제는

 

하위 클래스 상속 및 호출 불가능하고 외부 직접적인 접근도 불가능함

 

본 클래스 내부에서만 사용가능

 

 

protected는 p1._age는 가능했는데 private는 진짜로 p1.__age도 불가능함

 

하지만 메소드를 활용해서 간접적인 호출은 여전히 가능

 

 

5. getter와 setter method

 

실제로 직접적인 접근은 못하게 하면서도 간접적으로 접근할 수 있게 만드는 method들

 

 

5-1) getter method : 변수의 값에 접근할 수 있게 하는 메소드

 

>> @property 데코레이터 사용

 

 

5-2) setter method: 변수의 값을 설정, 변경할 수 있게 하는 메소드

 

>> @(변수명).setter 데코레이터 사용

 

 

함부로 바꾸다가 큰일나는 경우, 개발자들끼리 그냥은 건들이지 맙시다라고 표시해놓으면서 사고 방지책으로 막아놓는거

 

 

위와 같이 age에 대한 getter method와 setter method를 설정할 수 있는데

 

원래는 protected여도 p1.age하면 접근이 불가능하지만 이제는 p1.age해도 접근이 가능하다

 

age()는 분명히 메소드인데도 마치 변수처럼 접근하게 된다

 

근데 메소드니까 p1.age()해도 가능할줄 알았는데 이거는 불가능함

 

 

값에 직접 접근하여 변경하는 것도 가능하고,

 

setter method에서 값을 변경할때 특정 값 이하로 변경하면 에러나도록 설정되어 있는데

 

이렇게 우회적으로 변경하도록 만들면 잘못된 변경이 될 경우 이러한 알림이 가능하도록 만들 수 있다

 

 

물론 protected는 p1._age로 접근하고 직접 변경하는 것도 가능하지만 이러면 잘못 변경할때 에러처리가 불가능함

 

 

그래서 누군가가 실수로 age에 음수를 넣는다거나 그런 점을 방지할 수 있다

 

 

TAGS.

Comments