目录

1.多态

2.__new__魔术方法

  2.1 关于魔术方法__new__

  2.2 基本语法

  2.3 __new__ 触发时机快于构造方法

  2.4 __new__ 和 __init__ 参数一一对应

  2.5 关于__new__的注意点

3.单态模式

4.连贯操作

5.小人射击项目

多态

什么是多态?

不同的子类对象,调用相同的父类方法,产生不同的执行结果

多态的关键字:继承和改写

下面的例子完美展示了python的多态:

# 定义Soldier类,让空军陆军海军继承这个类
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 attack(self):
print("[空军]空中夺导弹,手撕飞机,在空中打飞机,精准弹幕") def back(self):
print("[空军]高中跳伞,落地成盒") # 实例化陆军对象
army_obj = Army()
# 实例化海军对象
navy_obj = Navy()
# 实例化空军对象
af_obj = AirForce() lst = [army_obj,navy_obj,af_obj] # 对象列表
strvar = """
1.所有兵种开始攻击训练
2.所有兵种开始撤退训练
3.空军练习攻击,其他兵种练习撤退
"""
print(strvar)
num = input("将军请下令,选择训练的种类")
for i in lst:
if num == "":
i.attack()
elif num == "":
i.back()
elif num == "":
if isinstance(i,AirForce):
i.attack()
else:
i.back()
else:
print("将军~ 风太大 我听不见~")
break

__new__魔术方法

关于魔术方法__new__

1.触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)

2.功能:控制对象的创建过程

3.参数:至少一个cls接受当前的类,其他根据情况决定

4.返回值:通常返回对象或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
# (3) 不返回任何对象
return None obj = MyClass()
print(obj)

__new__ 触发时机快于构造方法

__new__ 用来创建对象

__init__ 用来初始化对象

先创建对象,才能在初始化对象,所以__new__快于__init__

class Boat():
def __new__(cls):
print(2)
return object.__new__(cls)
def __init__(self):
print(1) obj = Boat() # 因为__new__比__init__先执行,所以会先打印2后打印1.

__new__ 和 __init__ 参数一一对应

单个参数的情况

class Boat():
def __new__(cls,name):
return object.__new__(cls)
def __init__(self,name):
self.name = name obj = Boat("友谊的小船说裂开就裂开")
print(obj.name)

多个参数的情况

# 当__init__参数很多的时候,在__new__方法使用*args和**kwargs收集所有的参数!!

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)

关于__new__的注意点

如果返回的对象不是自己本类中的对象,不会触发本类的构造方法

"""如果返回的对象不是自己本类中的对象,不会触发本类的构造方法"""
class MyClass():
pty = 200
obj = MyClass() class Boat():
def __new__(cls,*args,**kwargs):
return object.__new__(cls) # 返回的是自己类的对象,会触发__init__方法
# return obj # 返回的不是自己的对象,所以不会触发下面的__init__方法
# return None # 没有返回对象,不可能触发__init__方法
def __init__(self):
print("构造方法被触发")
obj = Boat()
print(obj)

单态模式

什么是单态模式?

一个类,无论实例化多少个对象,都有且只有一个对象

单态模式的应用场景

优点:节省内存空间,提升执行效率

针对于不要额外对该对象添加成员的场景(比如:mysql增删改查)

基本语法

class SingleTon():
__obj = None
def __new__(cls):
if cls.__obj is None:
# 把创建出来的对象赋值给私有成员__obj
cls.__obj = object.__new__(cls)
return cls.__obj obj1 = SingleTon()
obj2 = SingleTon()
obj3 = SingleTon()
print(obj1,obj2,obj3) """
第一次实例化对象时候, 创建一个对象赋值给cls.__obj,返回 cls.__obj
第二次实例化对象时候, 判定cls.__obj is None: 不成立, 直接返回上一次创建好的那一个对象
第三次实例化对象时候, 判定cls.__obj is None: 不成立, 直接返回上一次创建好的那一个对象
"""

单态模式+构造方法

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("A")
obj2 = SingleTon("B")
print(obj1.name)
print(obj2.name)
# 打印出来的是两个B,原因如下
'''
obj1 = SingleTon(宋云杰) self.name = "A"
obj2 = SingleTon(戈隆) self.name = "B"
self 代表的是本对象 第一次实例化对象时候,创建一个对象,赋值name为A
第二次实例化对象时候,因为 cls.__obj is None不满足,返回上一个创建好的对象
为上一个对象的name这个属性赋值 为B
obj1 和 obj2 所指代的对象是同一个对象 obj1.name => B
obj2.name => B 其实有些相当于是B把A覆盖了,因为B和A指向同一个对象
'''

连贯操作

连贯操作,通过在类中的__init__方法中传入obj对象,进而实现对象.对象.对象.属性的这种连贯操作

通过.不停的调用下一个对象的操作就是连贯操作

1.小试牛刀

class MyClass1():
pth1 = 10 class MyClass2():
def __init__(self,obj):
self.obj = obj obj = MyClass1()
obj2 = MyClass2(obj)
# 对象.对象.属性
# obj2.obj = obj
# obj.pth1 = 10
print(obj2.obj.pth1) #

2.升级版

class MyClass1():
pty1 = 101
def func1(self):
print("我是func1函数") class MyClass2():
def __init__(self,obj):
self.pty2 = obj def func2(self):
print("我是func2函数") class MyClass3():
pty3 = 103
def __init__(self,obj):
self.pty3 = obj def func2(self):
print("我是func3函数") obj1 = MyClass1()
obj2 = MyClass2(obj1)
obj3 = MyClass3(obj2) # 使用obj3调用func1方法?
# 对象.pty3 => obj2 | obj2.pty2 => obj1 | obj1.func1()
obj3.pty3.pty2.func1()
print(obj3.pty3.pty2.pty1)
obj3.pty3.func2()

连贯操作小项目->小人射击

小人射击的项目需求

小人射击项目的文件结构

文件夹下:

package包中:

小人射击项目的代码实现

main.py(主函数)

# ### 小人射击
"""面向对象的核心思想: 把对象当做程序中的一个最小单元,让对象操作一切"""
"""
弹夹:
属性: 子弹数量 bulletcount
方法: 无
枪 :
属性: 弹夹
方法: 射击 shoot
人 :
属性: 枪
方法: (1) 射击 (2) 换子弹
"""
from package.bulletbox import BulletBox
from package.gun import Gun
from package.person import Person # 先创建弹夹
danjia = BulletBox(20)
# 在创建一杆枪
ak47 = Gun(danjia)
# 在创造一个人
songyunjie = Person(ak47,"宋云杰") # 小人射击
if __name__ == "__main__":
# 射击
songyunjie.fire(15)
# 填充
songyunjie.fillcount(10)
# 在射击
songyunjie.fire(150)

bulletbox.py(弹夹)

# ### 弹夹类

class BulletBox():
def __init__(self,bulletcount):
self.bulletcount = bulletcount

gun.py(枪)

# ### 枪类

class Gun():
def __init__(self,bulletbox):
# 存放的是弹夹对象
self.bulletbox = bulletbox def shoot(self,shootcount):
if self.bulletbox.bulletcount < shootcount:
print("对不起,请先填充子弹~")
else:
# 剩余的子弹 = 总的子弹数量 - 射击的数量
self.bulletbox.bulletcount -= shootcount
print("突" * shootcount , "你射出了{}发,还剩下{}发".format(shootcount,self.bulletbox.bulletcount))

person.py(人)

# ### 人类
class Person():
def __init__(self,gun,name):
self.gun = gun
self.name = "宋云杰" # 填充子弹
def fillcount(self,fillnum):
# 往弹夹里面赛子弹
# self.枪对象 -> 弹夹对象 -> 弹夹数量属性
self.gun.bulletbox.bulletcount += fillnum # 射击
def fire(self,num):
print("{}此刻正在野外射击~".format(self.name))
# 枪对象.shoot
self.gun.shoot(num)

关于小人射击项目的总结

day24:多态&魔术方法__new__&单态模式的更多相关文章

  1. 032.Python魔术方法__new__和单态模式

    一 __new__ 魔术方法 1.1 介绍 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前) 功能:控制对象的创建过程 参数:至少一个cls接受当前的类,其他根据情况决定 返回值 ...

  2. Learn day7 继承(单、多、菱形)\多态\魔术方法\装饰器\异常

    1.继承 1.1 单继承# ### 继承 """ (1) 单继承 (2) 多继承 至少2个类,子类和父类 一个类继承另外一个类,当前类是子类 (衍生类) 被继承的这个类是 ...

  3. day19-Python运维开发基础(类的魔术方法)

    1. __new__魔术方法 # ### __new__ 魔术方法 ''' 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前) 功能:控制对象的创建过程 参数:至少一个cls接受当 ...

  4. PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化)/约束类型/魔术方法小结

      前  言  OOP  学习了好久的PHP,今天来总结一下PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化). 1  PHP中的抽象 ...

  5. Python的程序结构[1] -> 方法/Method[2] -> 魔术方法 __init__ / __del__ / __new__

    魔术方法 / Magic Method 魔法方法就是可以给你的类增加魔力的特殊方法(实质应称为特殊方法,魔术方法在JavaScript中有所体现,对象具有不透明特性,而且无法在自定义对象中模拟这些行为 ...

  6. Python的程序结构[1] -> 方法/Method[3] -> 魔术方法 __getattr__ 与代理模式

    __getattr__ 方法 __getattr__ 方法当对象调用内部属性(包括方法等)且未找到对应属性的时候会调用的特殊方法.利用这一特性,可是对函数实现一个代理模式. __getattr__方法 ...

  7. PHP中设计模式以及魔术方法

    1.设计模式        1.1单例模式        口诀:三私一公 1.私有的静态属性用来保存对象的单例 2.私有的构造方法用来阻止在类的外部实例化 3.私有的__clone阻止在类的外部clo ...

  8. Python 基础之面向对象之常用魔术方法

    一.__init__魔术属性 触发时机:实例化对象,初始化的时候触发功能:为对象添加成员,用来做初始化的参数:参数不固定,至少一个self参数返回值:无 1.基本用法 #例:class MyClass ...

  9. Python魔术方法-Magic Method

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...

随机推荐

  1. scala 数据结构(一):数据结构简介

    1 数据结构特点 scala集合基本介绍 1)Scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问 2)两个主要的包: 不可变集合:scala.collection.immutable ...

  2. vue中使用elmentUI的Upload组件提交文件和后台接收

    1.参考此博客,希望有以下知识储备 vue的路由,跨域请求,springboot2.X,html,已经阅读elementUI官网中关于upload组件的详细介绍. 2.废话不多说,直接讲解细节. 前台 ...

  3. html 转义和反转义

    public static void main(String[] args) {// String html = "<img style=\"width: 100%; hei ...

  4. Java冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序

    冒泡排序   冒泡排序是一种简单的排序算法.它重复地走访过要排序地数列,一次比较两个元素,如果它们地顺序错误就把它们交换过来.走访数列地工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. ...

  5. ztree : checkbox 选中/不选中时动态添加/删除DOM元素

    先上代码. var IDMark_Switch = "_switch", IDMark_Icon = "_ico", IDMark_Span = "_ ...

  6. Python 100个样例代码【爆肝整理 建议收藏】

    本教程包括 62 个基础样例,12 个核心样例,26 个习惯用法.如果觉得还不错,欢迎转发.留言. 一. Python 基础 62 例 1 十转二 将十进制转换为二进制: >>> b ...

  7. 【JVM之内存与垃圾回收篇】虚拟机栈

    虚拟机栈 虚拟机栈概述 由于跨平台性的设计,Java 的指令都是根据栈来设计的.不同平台 CPU 架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同 ...

  8. 感知机算法(PLA)代码实现

    目录 1. 引言 2. 载入库和数据处理 3. 感知机的原始形式 4. 感知机的对偶形式 5. 多分类情况-one vs. rest 6. 多分类情况-one vs. one 7. sklearn实现 ...

  9. @Autowired @Qualifier

    spring2.1中允许用户通过@Autowired注解对Bean的属性变量.属性Setter方法以及构造函数进行标注,配合AutowiredAnnotationBeanProcessor完成Bean ...

  10. Java Web(2)-jQuery下

    一.jQuery的属性操作 html() 它可以设置和获取起始标签和结束标签中的内容,跟 dom 属性 innerHTML 一样. text() 它可以设置和获取起始标签和结束标签中的文本, 跟 do ...