面向对象03-多态&元类(多态 面向对象)
liebian365 2025-01-31 13:57 24 浏览 0 评论
1.多态:派生类继承基类,基类的方法可以选择重写也可以不重写,而重写基类就叫多态!
基类的作用是定义一系列成员规范,告诉所有继承该基类的派生类,内部都需要实现基类的方法。
2.抽象基类:含抽象方法的类就叫抽象基类;
抽象基类创建语法:
#第一步:导包
from abc import ABCMeta
#第二步:定义抽象基类,定义关键字形参metaclass
class AbstractClass(object,metaclass = ABCMeta):
#如果一个类继承type,是一个自定义的元类,元类是创建类的类
抽象基类没有__call__,不能被实例化,只能继承;抽象基类就是“父类”;抽象基类并不是只有抽象方法,
也有其他类型的方法;
3.抽象方法:没有实现方法体的方法
抽象方法创建语法:
from abc import abstractmethod
#添加装饰器@abstractmethod,方法体pass占位,方法空
@abstractmethod
def abstractMethod(self):
pass
#抽象方法在抽象类内部不调用也不用定义方法体;派生类继承抽象类后必须重写抽象基类内部的抽象方法;
抽象方法不能定义为私有,大部分情况下,抽象基类中的抽象方法一般会定义公有或受保护的成员;派生类
重写抽象基类方法时,需要按照抽象方法的访问修饰符进行重写!
4.运算符重载与内置魔术方法重写:使自定义的类可以实现像python标准库中的内置类同样的操作;如__init__添加属性重写;【重载代码参考homework代码】
对象字面值方法重写:---->实现对象字面值表示,自定义类内部没有重写__str__,因此无法字面值表示
__str__:重写这个方法实现类型转换;
算术运算符重载:只要自定义实例与标准库实例做算术运算,正向反向都需要重载
+:__add__(self,other)other--->right,__radd__(self,lhs) l--->left
注意:当参与运算符的两个对象中,运算符左边的对象内部找不到该运算符的重载方法,
那么会进入运算符右边对象,去查找这个对象的反向运算符方法,如果有对应的反向运算符方法,
则继续执行运算逻辑,否则报错!
-:__sub__,__rsub__
*:__mul__,__rmul__
/:__truediv__,__rtruediv__
//:__floordiv__,__rfloordiv__
**:__pow__,__rpow__
%:__mod__,__rmod__
复合算术运算符重载:rhs只有正向运算符没有反向
+=:__iadd__
-=:__isub__
*=:__imul__
/=:__itruediv__
//=:__ifloordiv__
%=:__imod__
**=:__ipow__
比较运算符重载:
>:__gt__
<:__It__
>=:__ge__
<=:__le__
==:__eq__
!=:__ne__
in not in 运算符,item
in:__contains__
not in __contains__
数字类型常用方法及重写
__int__
__float__
......
序列类型:
__str__
__setitem__
__len__
__getitem__
5.标准库基类object:
object基类是python3.x新式类采用的默认继承基类,规定了python下每个内置标准库类或自定义类的成员规范,用于承担所有类的实例的创建及销毁功能!
对象构造原理:
__new__是一个静态方法,不会等待类实例化时读取至内存进行空间分配,在类进行定义的过程中完成了内
存空间分配;
一个类得到自己的实例,在自身默认实现__new__,调用基类的object的__new__,将其本身(cls)作为参数
传递给object的__new__中,由object的__new__接收类本身作为参数,为该类创建实例;
也就是说当重写一个类的__new__时,必须返回return object.__new__(cls)
def __new__(cls, *args, **kwargs ):
return object.__new__(cls)
上述中类的实例已被创建,但该类没有任何属性及方法,下一步由__init__进行初始化
__init__调用时self所接受的方法来自__new__调用完毕后返回的结果(实例,实例来源于object.__new__(cls)返回的)
object总结:
1.继承自object的派生类具有object相似的结构,都有必须得魔术方法、魔术属性;
2.自定义类的实例创建全部由object基类实现好的方法;
3.自定义类不仅可以直接调用object实现好的方法,还可以选择在自身类中重写该方法:多个类同时重写object
基类中的某方法,构成多态;如果重写的方法是一个运算符方法,就形成了运算符重载;
4.无论构造出多么复杂的继承关系,继承最终都会止于object,一定会形成一个有向无环图结构,为新式类设计
的MRO算法实现更方便的管理复杂的多继承结构!
即为更好的实现面向对象思想所有的类默认继承自object基类;
6.元类及自定义元类应用
type就是python中的元类,即创建类的类,称为元类!对于元类而言,它本身也是一个类对象,在python中,所有对象都是由元类创建的,元类也是元类创建的,元类类型type!type(object),返回对象类型,type(name,bases,dict)创建一个新类!
元类创建类对象语法:
new_type = type(name, bases, members)
name:类名,str类型
bases:当前类继承的关系,tuple类型
members:当前类对象初始化成员,dict类型
通过元类创建的的类的类型是type类型;
class 类名 === 类名 = type(传递上述三个参数)
使用元类的目的是限制类的创建行为!
类名()创建实例,是因为元类实现了__call__方法!
2.实现call方法思路:
元类的__call__内部,具备以下三个操作:
A.调用元类创建的实例,自定义类的__new__,自定义类实例化一个空对象
B.调用元类创建的实例,自定义类的__init__,自定类初始化实例对象
c.返回元类创建的实例,自定义类为自身创建并初始化实例的对像
实现一个自定义元类的关键步骤,就是重写元类中的__call__方法;
自定义元类的实现:
第一步普通类继承type,创建出来的类就是自定义元类;
class DemoMetaClass(type):
第二步创建类时如果要使用自定义元类,就通过metaclass关键字参数修改:
class Myclass(object,metaclass = 自定义元类的名称)即DemoMetaClass
——单例模式:实现一个类只能创建一次实例
class SingletonMetaClass(type):
def __call__(cls, *args, **kwargs):
'''
重写call方法,实现单例模式
:param args:
:param kwargs:
:return:
'''
if not hasattr(cls, 'instances'):
#cls.instances = type.__call__(cls)
cls.instances = super(SingletonMetaClass,cls).__call__(*args,**kwargs)
print("您已创建该类的实例对象,实例对象为:{}".format(cls.instances))
return cls.instances
class MyDemo(object,metaclass=SingletonMetaClass):
pass
元类实现创建的成员均为私有属性:
class MustPrivateMetaClass(type):
'''
通过此元类规定每一个自定义类,其内部创建的成员,都是私有成员
'''
def __call__(cls, *args, **kwargs):
obj = cls.instances = super(MustPrivateMetaClass,cls).__call__(*args,**kwargs)
#实现的限制逻辑
obj.__dict__ = {
'_{}__{}'.format(cls. __name__,key):value for key,value in obj.__dict__.items()
}
print(obj.__dict__)
return obj
class MyDemo(object,metaclass=MustPrivateMetaClass):
def __init__(self):
self.name = 'jack'
self.age = '20'
class 元类名称(type):
def __call__(self, *args, **kwargs):
# 步骤1:调用__new__方法创建元类的实例
# 步骤2:调用__init__方法初始化元类的实例
# 元类实例的限制行为修改逻辑
# 最后:一定一定返回元类的实例
return 元类的实例
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)