고급 파이썬 (XVI)의 객체 지향 ---- ~ 캡슐화, 다형성, 오리 모델, 슈퍼 원칙 (단일 상속의 원리, 다중 상속의 원칙)

고급 파이썬 (XVI)의 객체 지향 ---- ~ 캡슐화, 다형성, 오리 모델, 슈퍼 원칙 (단일 상속의 원리, 다중 상속의 원칙)

다이애나 캡슐화, 다형성

패키지 :

           당신은 또한 꺼낼 수있는 장소에 패키지 뭔가

           정적 속성 클래스를 설정하거나 어떤 객체 메소드를 제공하는 개체는 곳의 오브젝트에 포장 될 수있다

다형성 :

           파이썬 기본 지원 다형성, 거래의 다양한 형태를 갖는 다형성 (polymorphism)을 의미

           1. 다형성 코드의 유연성을 증가시킬 수있다;

           2. 부모 클래스 상속의 방법과 전제를 오버라이드 (override);

           3. 기술을 호출하는 방법은 클래스의 내부 설계에 영향을주지 않습니다

           개인 이해함 달성하는 다양한 인터페이스를 재사용 인터페이싱

#### 例1:
#序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系

#str,list,tuple都是序列类型
s=str('hello')
l=list([1,2,3])
t=tuple((4,5,6))

#我们可以在不考虑三者类型的前提下使用s,l,t
s.__len__()
l.__len__()
t.__len__()

len(s)
len(l)
len(t)





#### 例2:

import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('say aoao')
        
peo=People()
dog=Dog()
pig=Pig()

#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()

#更进一步,我们可以定义一个统一的接口来使用
def func(obj):
    obj.talk()
    

오리 모델 : 스타일의 동적 유형

정의 :

           당신은 새가 오리처럼 걷고 볼 때, 오리처럼 수영 오리처럼,이 새가 오리라고 할 수있다 꽥꽥.

개념 :

           오리 형에서 문제의 유형은 객체 자체가 아니라 그것을 어떻게 사용됩니다. 예를 들어, 언어가 오리의 종류를 사용하지 않는, 우리는 형 오리의 객체를받는 함수를 쓸 수 있으며 산책 및라는 방법을 호출합니다. 오리 종류의 언어, 이러한 기능은 객체의 모든 유형을 수용하고, 도보이라는 방법을 호출 할 수 있습니다. 이러한 방법이 존재하지 않는 호출해야하는 경우 런타임 오류로 이어질 것입니다. 그러한 행동은 가고, 기능, 위 제표에 대한 의사 결정의 유형 그러므로 방법 이름을지도에 허용 될 객체의 메소드를 호출하는 그런 권리가 있습니다. 오리 유형은 일반적으로 방법과 함수 인수의 유형을 테스트하지 때문에, 오히려 적절한 사용을 보장하기 위해 문서, 명확한 코드 및 테스트에 의존한다. 정적으로 입력 된 언어 사용자로부터 동적으로 입력 된 언어를 핸들 종종 따라서 오리와 확장 성을 장점과 언어의 동적 특성의 제약 조건의 유형에 영향을 미치는, (작업 전) 일부 정적 타입 검사를 추가하려고합니다. (참조 CSDN의 juunny 발췌 만)

class A:

    def login(self):
        pass

    def register(self):
        pass


class B:

    def login(self):
        pass

    def register(self):
        pass

# A,B两个类,没有任何关系,独立两个,但是里面的功能相似,所以python一般会将类似于A,B两个类
# 里面的相似的功能让其命名相同.
# A,B虽然无关系,但是很默契的制定了一个规范.让你使用起来更方便.


## 个人理解:
    #你可以定义一个公共的接口, 简化代码 .牛逼人都这么干
    def func(obj):
       obj.register()
       obj.login()

       자세한 기사 다형성

두 클래스 제약 다이애나

표준화 된 디자인 :

           통합 인터페이스

###  pay函数就作为 统一的接口  不论用哪个平台调用都是使用pay函数

class QQ(Payment):
    def pay(self,money):
        print(f'支付了 {money}')

class Ali(Payment):
    def pay(self,money):
        print(f'支付了 {money}')

class WeChat(Payment):
    def fuqian(self,money):
        print(f'支付了 {money}')

# 定义接口函数
def pay(obj,money):
    obj.pay(money)

q=QQ()      # 实例化对象
a=Ali()
w=WeChat()

pay(q,200)  # 调用接口 实现功能
pay(a,100)
pay(w,1200)

부모는 제약 조건을 설정합니다

### 父类的约束不是强制性的,不重写父类的 pay函数 也可以调用子类本身的函数,完成支付功能

class Payment:          

    def pay(self,money):
        raise  Exception('子类必须继承父类pay方法')   # 当子类执行接口函数时,调用函数名与父类不一致,父类pay函数主动抛出一个异常


class QQ(Payment):
    def pay(self,money):
        print(f'支付了 {money}')

class Ali(Payment):
    def pay(self,money):
        print(f'支付了 {money}')

class WeChat(Payment):
    def fuqian(self,money):
        print(f'支付了 {money}')

# 定义接口

def pay(obj,money):
    obj.pay(money)

q=QQ()          # 实例化对象
a=Ali()
w=WeChat()

pay(q,200)      
pay(a,100)
pay(w,1200)     # 由于 子类没有重写父类的pay方法, 父类会主动抛出一个异常

아날로그 추상적 인 개념 (사양을 지정), 제약의 설립.

### 强制性约束, 必须重写父类的方法 

from abc import abstractmethod, ABCMeta  # 导入抽象类 和 抽象元类
    
class Payment(metaclass=ABCMeta):     # 定义这个类是一个抽象类
    @abstractmethod                 # 给父类的 pay 函数添加抽象方法装饰器. 当子类没有重写父类方法,实例化对象时,就会报错  
    def pay(self, money):
        pass


class QQ(Payment):
    def pay(self, money):
        print(f'支付了 {money}')


class Ali(Payment):
    def pay(self, money):
        print(f'支付了 {money}')


class WeChat(Payment):
    def fuqian(self, money):        
        print(f'支付了 {money}')
    
    # 重写父类的pay函数,就不会报错.  不重写就会报错
    def pay(self, money):
        pass


# 定义接口

def pay(obj, money):
    obj.pay(money)


q=QQ()
a=Ali()
w=WeChat()      # 1.  实例化对象时, 就会报错.  必须重写父类的pay函数 , 

pay(q,200)
pay(a,100)
pay(w,1200) 


# 由于抽象方法引自与Java的抽象类. so 原理相同
###  抽象类 不能被实例化 ,只能被继承
aa=Payment()   
# TypeError: Can't instantiate abstract class Payment with abstract methods pay

수요일 슈퍼 깊이 이해

### super() 并不是 执行父类的方法
    
    # 单继承: super() 肯定执行父类的方法
    
    # 多继承:  super(S,self)严格按照self(就是当前对象) 从属于类的mro的执行顺序,执行 S类的下一位
    
class A:
    def f1(self):
        print('in A')

class Foo(A):
    def f1(self):
        super(Foo,self).f1()
        print('in Foo')     # 2  按照继承顺序来找, 再执行Foo

class Bar(A):
    def f1(self):
        print('in Bar')     # 1 按照继承顺序来找, 先执行Bar

class Info(Foo,Bar):    

    def f1(self):
        super(Info,self).f1()    # 是从Info当前类开始,
        print('in Info f1')     # 3  按照继承顺序来找, 再执行Info
            

obj = Info()
print(Info.mro())   # obj对象的 继承顺序[Info, Foo, Bar, A]
obj.f1()
# 结果:  in Bar,   in Foo ,   in Info f1


####多继承 ,  super指定继承哪个类,就从这个类的下一个类执行
class A:
    def f1(self):
        print('in A')

class Foo(A):

    def f1(self):
        super().f1()
        print('in Foo')

class Bar(A):

    def f1(self):  # self = obj
        print('in Bar')

class Info(Foo,Bar):

    def f1(self):  # self = obj
        super(Foo,self).f1()     # 这里指定从Foo类继承. 按照多继承规则,会执行下一个类,也就是Bar
        print('in Info f1')

obj = Info()  
obj.f1()        # obj对象的 继承顺序[Info, Foo, Bar, A]

# 结果  : in Bar,  in Info f1

추천

출처www.cnblogs.com/dengl/p/11164662.html