一.多态:
- 不同的子类对象,调用相同的父类方法,产生不同的执行结果
- 关键字: 继承 , 改写
(1)示例
class Soldier():
def attack(self):
pass
def back(self):
pass
# 陆军
class Army(Soldier):
def attack(self):
print("[陆军]搏击,ufc,无限制格斗,太极,八卦,占星,制作八卦符")
def back(self):
print("[陆军]白天晨跑10公里,也行800百公里")
# 海军
class Navy(Soldier):
def attack(self):
print("[海军]潜泳水下30个小时,手捧鱼雷,亲自送到敌人的老挝,炸掉敌人的碉堡")
def back(self):
print("[海军]每小时在海底夜行800公里,游的比鲨鱼还快")
# 空军
class AirForce(Soldier):
def sttack(self):
print("[空军]空中夺导弹,手撕飞机,在空中打飞机,精准弹幕")
def back(self):
print("[空军]高中跳伞,落地成盒")
(2)实例化对象
<1>实例化陆军对象
army_obj = Army()
<2>实例化海军对象
navy_obj = Navy()
<3>实例化空军对象
af_obj = AirForce()
(3)调用
lst = [army_obj,navy_obj,af_obj]
strvar = '''
1.所有兵种开始攻击训练
2.所有兵种开始撤退训练
3.空军练习攻击,其他兵种练习撤退
'''
print(strvar)
num = input('将军请下令,选择训练的种类')
for i in lst:
if num == '1':
i.attack()
elif num == '2':
i.back()
elif num == '3':
if isinstance(i,AirForce):
i.attack()
else:
i.back()
else:
print('将军~,风太大,我听不见~')
break
二. __new__魔术方法
- 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
- 功能:控制对象的创建过程
- 参数:至少一个cls接受当前的类,其他根据情况决定
- 返回值: 通常返回对象或None
(1)基本语法
class MyClass2():
pty = 100
obj2 = MyClass2()
class MyClass():
def __new__(cls):
print(cls)
#类.方法(自定 义类) => 借助父类object创建MyClass这个类的对象
obj = object.__new__(cls)
# (1) 借助父类object创建自己类的一个对象
return obj
# (2) 返回其他类的对象
return obj2 # print(obj.pty) =>obj2.pty = 100
# (3) 不能返回任何对象
return None
obj = MyClass()
print(obj)
(2) __new__ 触发时机快于构造方法
- __new__ 用来创建对象
- __init__ 用来初始化对象
- 先创建对象,才能在初始化对象,所以__new__快于__init__
1 class Boat(): 2 def __new__(cls): 3 print(2) 4 return object.__new__(cls) 5 def __init__(self): 6 print(1) 7 8 obj = Boat()
(3) __new__ 和 __init__ 参数一一对应
<1>单个参数的情况
1 class Boat(): 2 def __new__(cls,name): 3 return object.__new__(cls) 4 def __init__(self,name): 5 self.name = name 6 7 obj = Boat('友谊小船说裂开就裂开') 8 print(obj.name)
<2>多个参数的情况
class Boat(): def __new__(cls,*args,**kwargs): return object.__new__(cls) def __init__(self,name,color,shangpai): self.name = name self.color = color self.shangpai = shangpai obj = Boat("泰坦尼克号","屎绿色","京A66688") print(obj.name) print(obj.color) print(obj.shangpai)
(4) 注意点
- 如果返回的对象不是自己本类中的对象,不会触发本类的构造方法
class MyClass(): pty = 200 obj = MyClass() class Boat(): def __new__(cls,*args,**kwargs): # return object.__new__(cls) # return obj return None def __init__(self): print("构造方法被触发") obj = Boat() print(obj)
三.单态模式
- 一个类,无论实例化多少个对象,都有且只有一个
- 优点:节省内存空间,提升执行效率
- 针对于不要额外对该对象添加成员的场景(比如:mysql的增删改查)
(1) 基本语法
1 class SingleTon(): 2 __obj = None 3 def __new__(cls): 4 if cls.__obj is None: 5 # 把创建出来的对象赋值给私有成员__obj 6 cls.__obj = object.__new__(cls) 7 return cls.__obj 8 obj1 = SingleTon() 9 obj2 = SingleTon() 10 obj3 = SingleTon() 11 print(obj1,obj2,obj3)
代码解析
- 第一次实例化对象时候, 创建一个对象赋值给cls.__obj,返回 cls.__obj
- 第二次实例化对象时候, 判定cls.__obj is None: 不成立, 直接返回上一次创建好的那一个对象
- 第三次实例化对象时候, 判定cls.__obj is None: 不成立, 直接返回上一次创建好的那一个对象
(2) 单态模式 + 构造方式
class SingleTon(): __obj = None def __new__(cls,*args,**kwargs): if cls.__obj is None: cls.__obj = object.__new__(cls) return cls.__obj def __init__(self,name): self.name = name obj1 = SingleTon('abc') obj2 = SingleTon('123') print(obj1.name)#123 print(obj2.name)#123
代码解析
- obj1 = SingleTon(abc) self.name = abc
- obj2 = SingleTon(123) self.name = "123"
- self 代表的是本对象
- 第一次实例化对象时候,创建一个对象,赋值name为abc
- 第二次实例化对象时候,因为 cls.__obj is None不满足,返回上一个创建好的对象
- 为上一个对象的name这个属性赋值为123
- obj1 和 obj2 所指代的对象是同一个对象
- obj1.name => 123
- obj2.name => 123