1.三大特性
封装
? 把很多数据封装到?个对象中. 把固定功能的代码封装到?个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了?个很?B的函数. 那这个也可以被称为封装. 在?向对象思想中. 是把?些看似?关紧要的内容组合到?起统?进?存储和使?. 这就是封装.
继承
? ?类可以?动拥有?类中除了私有属性外的其他所有内容. 说?了, ??可以随便?爹的东?. 但是朋友们, ?定要认清楚?个事情. 必须先有爹, 后有??. 顺序不能乱, 在python中实现继承非常简单. 在声明类的时候, 在类名后?添加?个?括号,就可以完成继承关系. 那么什么情况可以使?继承呢? 单纯的从代码层?上来看. 两个类具有相同的功能或者特征的时候. 可以采?继承的形式. 提取?个?类, 这个?类中编写着两个类相同的部分. 然后两个类分别取继承这个类就可以了. 这样写的好处是我们可以避免写很多重复的功能和代码. 如果从语义中去分析的话. 会简单很多. 如果语境中出现了x是?种y. 这时, y是?种泛化的概念. x比y更加具体. 那这时x就是y的?类. 比如. 猫是?种动物. 猫继承动物. 动物能动. 猫也能动. 这时猫在创建的时候就有了动物的"动"这个属性. 再比如, ?骨精是?个妖怪. 妖怪天?就有?个比较不好的功能叫"吃?", ?骨精?出?就知道如何"吃?". 此时 ?骨精继承妖精.
多态
? 同?个对象, 多种形态. 这个在python中其实是很不容易说明?的. 因为我们?直在?. 只是没有具体的说. 比如. 我们创建?个变量a = 10 , 我们知道此时a是整数类型. 但是我们可以通过程序让a = "alex", 这时, a?变成了字符串类型. 这是我们都知道的. 但是, 我要告诉你的是. 这个就是多态性. 同?个变量a可以是多种形态
2.鸭子类型
python中有一句谚语说的好,你看起来像鸭子,那么你就是鸭子。
class A: def f1(self): print('in A f1') def f2(self): print('in A f2') class B: def f1(self): print('in A f1') def f2(self): print('in A f2') obj = A() obj.f1() obj.f2() obj2 = B() obj2.f1() obj2.f2()
? A 和 B两个类完全没有耦合性,但是在某种意义上他们却统一了一个标准。
? 对相同的功能设定了相同的名字,这样方便开发,这两个方法就可以互成为鸭子类型。
? 这样的例子比比皆是:str tuple list 都有 index方法,这就是统一了规范。
? str bytes 等等 这就是互称为鸭子类型。
3.类的约束
? 类的约束有两种:
第一种:抛出异常
? 提取?类. 然后在?类中定义好?法. 在这个?法中什么都不??. 就抛?个异常就可以了. 这样所有的?类都必须重写这个?法. 否则. 访问的时候就会报错.
class Payment: def pay(self,money): raise Exception("子类设置pay方法") class QQpay(Payment): def pay(self,money): print(f"QQ支付{money}金额") class Alipay(Payment): def pay(self,money): print(f"支付宝支付{money}金额") class Wechatpay(Payment): def zhifu(self,money): print(f"微信支付{money}金额") def pay(obj,money): obj.pay(money) obj1 = QQpay() pay(obj1,100) obj2 = Alipay() pay(obj2,200) obj3 = Wechatpay() pay(obj3,300) """ QQ支付100金额 Traceback (most recent call last): 支付宝支付200金额 File "D:/pycharm demo/练习/代码练习.py", line 30, in <module> pay(obj3,300) File "D:/pycharm demo/练习/代码练习.py", line 20, in pay obj.pay(money) File "D:/pycharm demo/练习/代码练习.py", line 3, in pay raise Exception("子类设置pay方法") Exception: 子类设置pay方法 """
第二种:使用元类
? 使?元类来描述?类. 在元类中给出?个抽象?法. 这样?类就不得不给出抽象?法的具体实现. 也可以起到约束的效果.
from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self,money): pass class QQpay(Payment): def pay(self,money): print(f"QQ支付{money}金额") class Alipay(Payment): def pay(self,money): print(f"支付宝支付{money}金额") class Wechatpay(Payment): def zhifu(self,money): print(f"微信支付{money}金额") def pay(obj,money): obj.pay(money) obj1 = QQpay() pay(obj1,100) obj2 = Alipay() pay(obj2,200) obj3 = Wechatpay() pay(obj3,300) """ QQ支付100金额 Traceback (most recent call last): 支付宝支付200金额 File "D:/pycharm demo/练习/代码练习.py", line 63, in <module> obj3 = Wechatpay() TypeError: Can't instantiate abstract class Wechatpay with abstract methods pay """
4.super的深度剖析
class A: def f1(self): print('in A f1') def f2(self): print('in A f2') class Foo(A): def f1(self): super().f2() print('in A Foo') obj = Foo() obj.f1() """ 'in A f2' 'in A Foo' """ 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): print('in Bar') class Info(Foo,Bar): def f1(self): super().f1() print('in Info f1') obj = Info() obj.f1() ''' in Bar in Foo in Info f1 ''' print(Info.mro()) # [<class '__main__.Info'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <class '__main__.A'>, <class 'object'>] super()严格按照类的mro顺序执行
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): print('in Bar') class Info(Foo,Bar): def f1(self): super(Foo,self).f1() print('in Info f1') obj = Info() obj.f1() """ in Bar in Info f1 """