组合
继承是“is-a”关系,实现子类拥有父类的方法和属性,可以确定类之间的组织层次关系。组合是“has-a”关系,是一个类拥有另一个类的方法和属性(不一定是父类)。
[Python] 纯文本查看 复制代码 #继承实现代码的复用
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.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()
运行结果为:a1,a1,a1
a2,a2,a2
计算器
CPU对象: <__main__.CPU object at 0x0000025B4E18EBB0>
展示画面
Screen对象: <__main__.Screen object at 0x0000025B4E18EB50>
组合和继承都可实现代码复用,组合更多的是包含关系,而继承还包括了类之间的结构层次。
工厂模式
设计模式是面向对象语言特有的内容,比较流行的是GOF23中设计模式。对应初学者,先学习两个最常用的模式:工厂模式和单例模式。
工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。
[Python] 纯文本查看 复制代码 class CarFactory: #专门的工厂类进行汽车品牌的选择
def CreatCar(self,brand):
if brand == "奔驰":
return Benz()
elif brand == "宝马":
return BWM()
elif brand == "比亚迪":
return BYD()
else:
return "未知品牌,无法创建"
class Benz:
pass
class BWM:
pass
class BYD:
pass
m = CarFactory()
m1 = m.CreatCar("宝马")
m2 = m.CreatCar("比亚迪")
print(m1)
print(m2)
运行结果:<__main__.BWM object at 0x0000019D5BB9DFA0>
<__main__.BYD object at 0x0000019D5BB9DF70>
上述代码就是一个工厂模式的案例,专门创建了一个CarFactoryZ类进行汽车品牌的筛选,然后生成相应的汽车类。
单例模式
单例模式的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。该模式减少了对系统资源的开销。
单例模式一般需要对__init_()构造函数和__new__()函数进行重写。
[Python] 纯文本查看 复制代码 class Mysingleton:
__obj = None
__init_flag =True
def __new__(cls, *args, **kwargs):
if cls.__obj == None:
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,n):
if Mysingleton.__init_flag:
print("init....")
self.n = n
Mysingleton.__init_flag =False
a = Mysingleton("a")
b = Mysingleton("b")
print(a)
print(b)
运行结果为:init....
<__main__.Mysingleton object at 0x000001792D20EFA0>
<__main__.Mysingleton object at 0x000001792D20EFA0>
单例模式一般初始化一次,生成一个实例对象,从运行结果上来看,可以看出a和b是一个对象,内存地址都是一样的,单例模式通过定义类属性__obj,第一次调用时__obj为空,系统会创建一个新的对象赋值给__obj,在第二次调用时,因为__obj不为空,会直接返回之前的实例对象,不会再次创建,在初始化时因为定义了一个__init_flag标记,在调用一次后该标记变为False,因此再次调用时不会再次进行初始化。 |