Python基础学习Day8(下)(多重继承、多态、运算符重载、对象的浅拷贝深拷贝、组合、设计模式(工厂、单例))

多重继承

Python支持多重继承,一个子类可以有多个“直接父类”。 这样,就具备了“多个父类”的特点。但是由于,这样会被“类的整体层次”搞的异常复杂,尽量避免使用。

#多重继承
class A:
    def aa(self):
        print("aa")
class B:
    def bb(self):
        print("bb")
class C(B,A):#子类C有两个直接父类B和A
    def cc(self):
        print("cc")
c=C()
c.cc()
c.bb()
c.aa()#类A、B中的对象都可调用

在这里插入图片描述
在这里插入图片描述

MRO()方法

Python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左到右”按顺序搜索。
MRO(Method Resolution Order):方法解析顺序。我们可以通过mro()方法获得“类的层次结构”,方法解析顺序也是按照这个“类的层次结构”寻找的。

#多重继承
class A:
    def aa(self):
        print("aa")
    def say(self):
        print("say AAA")
class B:
    def bb(self):
        print("bb")
    def say(self):
        print("say BBB")
class C(B,A):#顺序是先B后A
    def cc(self):
        print("cc")
c=C()
c.say()

结果是调用B的方法
在这里插入图片描述

super()获得父类定义

在子类中,如果想要获得父类的方法时,我们可以通过super()来做。
super()代表父类的定义(看成代码),不是父类对象。

#测试super(),代表父类的定义,而不是父类的对象
class A:
    def say(self):
        print("A:",self)
class B(A):
    def say(self):
        #A.say(self)
        super().say()#获得父类的方法,与上面一句代码等价
        print("B:",self)
B().say()

在这里插入图片描述

多态

多态是指同一个方法调用由于对象不同可能产生不同的行为。
注意:
1.多态是方法的多态,属性没有多态。
2.多态的存在有2个必要条件:继承、方法重写

#测试多态
class Man:
    def eat(self):
        print("饿了,吃饭啦!")
class Chinese(Man):#继承
    def eat(self):#方法重写
        print("中国人用筷子吃饭")
class English(Man):
    def eat(self):
        print("英国人用叉子吃饭")
class Indian(Man):
    def eat(self):
        print("印度人用右手吃饭")
def manEat(m):
    if isinstance(m,Man):   #多态,一个方法调用,根据对象不同调用不同的方法
        m.eat()
    else:
        print("不能吃饭")
manEat(Chinese())
manEat(Indian())

在这里插入图片描述

特殊方法和运算符重载

常见的特殊方法统计如下:
在这里插入图片描述
每个运算符都对应了相应的方法:
在这里插入图片描述

#测试运算符的重载

class Person:
    def __init__(self,name):
        self.name=name
    def __add__(self, other):#加法重载
        if isinstance(other,Person):#判断other是否与Person类的实例属性同一类型
            return"{0}--{1}".format(self.name,other.name)
        else:
            return "不是同类对象,不能相加"

    def __mul__(self,other):#乘法重载
        if isinstance(other,int):
            return self.name*other
        else:
            return "不是同类对象,不能相乘"
p1=Person("Meidi")
p2=Person("Zhang")
x=p1+p2
print(x)
print(p1*3)

在这里插入图片描述

特殊属性

在这里插入图片描述
直接上例子!

#测试特殊属性
class A:
    pass
class B:
    pass
class C(B,A):
    def __init__(self,n):
        self.n=n
    def cc(self):
        print("cc")
c=C(3)
print(dir(c))   #返回对象的方法、属性列表
print(c.__dict__)  #对象的属性字典
print(c.__class__)  #对象所属的类
print(C.__bases__)  #类的(父)基类
print(C.__mro__)  #类层次结构
print(A.__subclasses__())  #子类列表

在这里插入图片描述

对象的浅拷贝和深拷贝

变量的赋值操作
只是形成两个变量,实际还是指向同一个对象
浅拷贝
Python拷贝一般都是浅拷贝。拷贝时,对象包含的子对象内容不拷贝。因此,源对象和拷贝对象会引用同一个子对象

深拷贝
使用copy模块的 deepcopy 函数,递归拷贝对象中包含的子对象。源对象和拷贝对象所有的子对象也不同

#测试对象的浅拷贝、深拷贝
import copy
class MobilePhone:
    def __init__(self,cpu,screen):
        self.cpu=cpu
        self.screen=screen
class CPU:
    def calculate(self):
        print("算数")
        print("cpu对象:",self)
class Screen:
    def show(self):
        print("显示")
        print("screen对象:",self)
#测试变量赋值
c1=CPU()
c2=c1
print(c1)
print(c2)
#测试浅复制
s1=Screen()
m1=MobilePhone(c1,s1)
m2=copy.copy(m1)

print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)

#测试深复制
m3=copy.deepcopy(m1)
print(m1,m1.cpu,m1.screen)
print(m3,m3.cpu,m3.screen)
D:\Anaconda3\python.exe D:/PycharmProjects/untitled/obj.py
<__main__.CPU object at 0x00000216284D1D68>
<__main__.CPU object at 0x00000216284D1D68>#变量赋值,指向同一对象
<__main__.MobilePhone object at 0x00000216284EE160> <__main__.CPU object at 0x00000216284D1D68> <__main__.Screen object at 0x00000216284EE128>
<__main__.MobilePhone object at 0x00000216284EED30> <__main__.CPU object at 0x00000216284D1D68> <__main__.Screen object at 0x00000216284EE128>#浅拷贝,只拷贝其本身,还是引用同一子对象
<__main__.MobilePhone object at 0x00000216284EE160> <__main__.CPU object at 0x00000216284D1D68> <__main__.Screen object at 0x00000216284EE128>
<__main__.MobilePhone object at 0x00000216266EC9B0> <__main__.CPU object at 0x0000021629546860> <__main__.Screen object at 0x00000216295469B0>#深拷贝,整个家族都拷贝了,引用不同的子对象

Process finished with exit code 0

组合

继承:“is-a”关系,从而实现子类拥有的父类的方法和属性。
“is-a” 关系指的是类似这样的关系:狗是动物,dog is animal。狗类就应该继承动物类。
组合: “has-a”关系,也能实现一个类拥有另一个类的方法和属性。”
has-a”关系指的是这样的关系:手机拥有 CPU。 MobilePhone has a CPU。

#使用继承实现代码的复用
class A1:
    def say_a1(self):
        print("a1,a1,a1")
class B1(A1):#继承
    pass
b1=B1()
b1.say_a1()
#使用组合实现代码的复用
class A2:
    def say_a2(self):
        print("a2,a2,a2")
class B2:
    def __init__(self,a):
        self.a=a
a2=A2()
b2=B2(a2)#组合,也可以与上一句合并写成b2=B2(A2())
b2.a.say_a2()

在这里插入图片描述

#组合has-a
class MobilePhone:
    def __init__(self,cpu,screen):
        self.cpu=cpu
        self.screen=screen
class CPU:
    def calculate(self):
        print("算数")
        print("cpu对象:",self)
class Screen:
    def show(self):
        print("显示")
        print("screen对象:",self)
m=MobilePhone(CPU(),Screen())  #组合
m.cpu.calculate()
m.screen.show()

在这里插入图片描述

设计模式_工厂模式实现

工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。

#测试工厂模式
class CarFactory:
    def create_car(self,brand):#工厂模式特点
        if brand=="奔驰":
            return Benz()
        elif brand=="宝马":
            return BMW()
        elif brand=="比亚迪":
            return BYD()
        else:
            return "未知品牌,无法创建"
class Benz:
    pass
class BMW:
    pass
class BYD:
    pass
factory=CarFactory()
c1=factory.create_car("奔驰")
c2=factory.create_car("比亚迪")
print(c1)
print(c2)

在这里插入图片描述

设计模式_单例模式实现

单例模式(Singleton Pattern)的核心作用是确保一个类只有一个实例,并且提供一 个访问该实例的全局访问点。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较 多的资源,如读取配置文件、产生其他依赖对象时,可以产生一个“单例对象”,然后永久 驻留内存中,从而极大的降低开销。
单例模式有很多方法,这里推荐用重写new方法、构造器方法

# 一种单例固定模式的测试
class MySingleton:
    __obj = None #定义一个类属性,做判断,对象保存在这里
    __init_flag = True
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)#通过父类的__new__(cls)创建实例
        return cls.__obj       #创建单例对象,并把建好的对象放到类属性上去,以后可以通过MySingleton.object访问
    def __init__(self,name):
        if MySingleton.__init_flag:
            print("init....")
            self.name = name
            MySingleton.__init_flag = False#T变F,再也不重构建
a = MySingleton("aa")
print(a)
b = MySingleton("bb")
print(b)

在这里插入图片描述
应用到工厂模式中:

# 单例模式
class CarFactory:
    __obj = None
    __init_flag = True
    def create_car(self, brand):
        if brand == "奔驰":
            return Benz()
        elif brand == "宝马":
            return BMW()
        elif brand == "比亚迪":
            return BYD()
        else:
            return "未知品牌,无法创建"
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)
        return cls.__obj       
    def __init__(self):
        if CarFactory.__init_flag:
            print("init CarFactory...")
            CarFactory.__init_flag = False
class Benz:
    pass
class BMW:
    pass
class BYD:
    pass
factory= CarFactory()
c1 = factory.create_car("奔驰")
c2 = factory.create_car("比亚迪")
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)

在这里插入图片描述
注意:

1)__new__方法是静态类方法,虽然没有加静态类方法的装饰器;

2)A继承object类,虽然通常可以省略object字样。但这里省略就无法执行__new__方法。若A继承其他类,同样可以使用object的__new__方法,也可以使用父类的__new__方法;

3)在实例化对象的时候,__new__方法在__init__方法之前执行;

4)__new__必须返回一个对象,才能给__init__初始化。

在网上搜索了单例模式相关博客,注意内容转载自CNblog博主「zaituzhong」的原创文章https://www.cnblogs.com/tingxin/p/12197904.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值