클라스 속성을 배우다보면, 상속하는 형태의 클라스들을 볼 수 있다.
상속은 이미 정의된 클래스에서 속성과 메서드를 물려받아 새로운 클래스를 생성하는 것을 말합니다.
=> 메소드와 속성을 재사용 => 코드 중복을 줄이고 모듈성을 높인다.
# 기본 클래스 (부모 클래스)
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
# 파생 클래스 (자식 클래스)
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
### class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
# 객체 생성 및 사용
dog = Dog("Buddy")
cat = Cat("Kitty")
print(dog.speak()) # 출력: Buddy says Woof!
print(cat.speak()) # 출력: Kitty says Meow!
Animal 이라는 클라스를 상속받아 그것의 속성인 name 과 메소드를 재사용한것.
현재 클래스의 부모클래스를 참조 -> 일종의 프록시 객체를 반환합니다.
간단히 말해 프록시 객체:
동일한 데이터베이스 사용, 하지만 python 코드 상에서의 행동을 변경하고 싶을 때 사용 => 커스터마이징
여기서 프록시 객체 프록시 모델은 위의 설명과 같게:
기존모델과 동일한 데이터베이스를 사용하지만,
그 모델의 python레벨에서의 행동(메타,옵션,메서도,매니저 등의 python코드상에서의 행동)만을 수정하는것이라고 말할 수 있다.
사용사례:
1. 같은 데이터에서 다른 phython레벨에서의 동작이 필요하다던가
2. 기본 쿼리셋 변경이 필요할때 : (relatedmanager와 같은)모델 메니저를 사용하여 변경
예) 장고에서의 프록시 모델
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class MyPerson(Person):
class Meta:
proxy = True
def do_something(self):
# 여기에 특정 동작을 정의
pass
위의 Person모델과 같은 데이터베이스 테이블을 사용하지만, 추가적인 do_something 이라는 메서드를 가지고 있다.
프록시 모델을 사용하려면, Meta 클래스 내에서 proxy 옵션을 True로 설정해야 한다.
이렇게 프록시 모데를 사용할때는
프록시 패턴은 객체 지향 설계 패턴 중 하나로,
-제어목적(접근 제어, 호출),
-지연로딩(일부분 초기화, 필요한 시점에 전체객체 로딩),
-로그,보안및 검증(메서드 호출 로그를 기록, 보안검사 수행,입력검증 등),
-분산시스템(원격프록시 사용 -> 원격객체의 로컬 인터페이스를 제공)
다양한 목적으로 프록시를 사용하여 기능을 제어하거나 확장할 수 있도록 합니다.
따라서 super().init() 형태로 부 초모 클래스의기화 메서드를 호출할 수 있습니다.
class BaseClass:
def __init__(self):
print("BaseClass의 __init__ 메서드 호출")
class DerivedClass(BaseClass):
def __init__(self):
super().__init__() # 여기서 BaseClass의 __init__ 메서드를 호출
print("DerivedClass의 __init__ 메서드 호출")
obj = DerivedClass()
#출력값
BaseClass의 __init__ 메서드 호출
DerivedClass의 __init__ 메서드 호출
코드를 보면 DerivedClass().__init__함수안에 부모클라스인 BaseClass()의 메소드인 __init__()을 호출하고 그 다음것을 실행 print("DerivedClass의 init 메서드 호출") 해주고 있는것.
객체지향 프로그래밍에서는 데이터와 그 데이터를 다루는 메서드들을 하나로 묶어 캡슐화합니다.
캡슐화된 객체는 외부에서 직접적으로 접근할 수 없으며, 메서드를 통해서만 데이터를 조작할 수 있습니다.
이를 통해 데이터의 보안성과 안정성을 높일 수 있습니다.
class Example:
def __init__(self):
self.__private_var = "I am private"
obj = Example()
# print(obj.__private_var) # 이 코드는 오류를 발생시킵니다.
# 그러나 다음과 같이 이름 변경된 속성에 접근하는 것은 가능합니다.
print(obj._Example__private_var) # "I am private"를 출력합니다.
캡슐화는 객체의 상태와 기능을 숨기고 (즉, 세부 구현을 숨기고) 공개 인터페이스만을 제공하는 개념입니다.
__ 접두사를 사용하여 변수나 메서드를 "비공개"로 설정하면 이름 변경(name mangling)이 발생하여 직접적인 접근이 어려워
=> __(더블언더스코어)접두사가 붙은 변수나 메소드는 이름 변경(name mangling)이 발생.
이 이름 변경의 결과로 실제 변수나 메서드 이름은
_클래스이름__변수명 또는
_클래스이름__메서드명 형태로 바뀝니다.
즉 위에 print(obj._Example__private_var)는 __priavate_var를 비공개 처리하면서 이름이 변경이 발생되어서=> _Example__private_var로 바뀌었기 때문에 접근이 가능해 프린트 되어진것이다.