面向对象03-多态&元类
xsobi 2025-01-03 19:36 1 浏览
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 元类的实例
- 上一篇:多态
- 下一篇:你了解多态吗?在哪里用过?
相关推荐
- 听说你还不知道Java代码是怎么运行的?
-
作者:Jay_huaxiao前言作为一名Java程序员,我们需要知道Java代码是怎么运行的。最近复习了深入理解Java虚拟机这本书,做了一下笔记,希望对大家有帮助,如果有不正确的地方,欢迎提出,感激...
- 如何开始学习JAVA编程?
-
#记录我的9月生活#...
- java后端开发需要学什么?
-
Java属于后端开发中最常见的语言之一,Java这种语言的体系比较中立,而且具备了构建多线程的能力,在许多大型互联网平台Java的应用范围特别广泛。 java后端主要涉及到如下4个技术: 第一、S...
- 细思极恐:你真的会写Java吗?
-
导语自2013年毕业后,今年已经是我工作的第4个年头了,总在做java相关的工作,终于有时间坐下来,写一篇关于java写法的一篇文章,来探讨一下如果你真的是一个java程序员,那你真的会写java吗?...
- 七年Java开发的一路辛酸史:分享面试京东、阿里、美团后的心得
-
前言我觉得有一个能够找一份大厂的offer的想法,这是很正常的,这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司...
- 我把Java基础编程及思维导图整理的超级详细,小白都能看懂
-
Java基础编程及其思维导图目录:Java学习导图一、Java基本语法1.关键字与标识符2.变量分类3.运算符4.流程控制二、数组1.数组概述2.一维数组3.二维数组4.数组常见算法5....
- Java 开发中的 9 个实用技巧:案例详解
-
Java开发中,总有一些技巧能够帮助我们提高代码质量和开发效率。下面,我们来分享9个Java技巧,每个技巧都附上实际案例,帮助你在工作中立刻应用。1.合理使用final关键字...
- Java 20年,以后将往哪儿走?
-
在今年的Java20周年的庆祝大会中,JavaOne2015的中心议题是“Java的20年”。甲骨文公司Java平台软件开发部的副总裁GeorgesSaab的主题演讲就将关注点放在了java...
- 推荐1个java快速开发项目,让你接私活不用愁
-
??大家好,我是小编南风吹,每天推荐一个小工具/源码,装满你的收藏夹,让你轻松节省开发效率,实现不加班不熬夜不掉头发!...
- 教你用Java开发一个简单的JVM
-
一、前言几年前,接到一个开发任务:用Java开发能运行Java智能合约的虚拟机。在开发Java智能合约时,只能使用智能合约SDK提供的类和一些Java常用类(8种基本数据类型包装类;String、Bi...
- java实战教程(一)软件开发流程&开发模式
-
这里小编为了方便处于不同学习阶段的童鞋,准备了三个系列的文章,java系列教程、java实战教程、java进阶教程,对于刚入坑的童鞋,可以先按照这三个系列教程一步步的了解,循序渐进,java实战系列教...
- Java 核心技术之入门指南:全面解析Java概述
-
大家好,这里是Java码牛!Java核心技术入门:全面解析Java概述一、引言Java,作为一门在当今信息技术领域中被广泛应用于企业级开发的主流编程语言,其核心技术的精准掌握对于众多开发者而言,具有...
- 小白如何轻松上手Java开发?
-
Java,这款流行的编程语言,被广大开发者所钟爱。但对于初学者来说,如何入门确实是一个大问题。尤其对于毫无经验的小白,从何处开始、如何推进,都是关键。本文将带你走进Java的世界,为你揭示从零到一的进...
- 初学Java应该知道的知识点:Java的程序开发是什么?
-
Java的程序开发是什么呢?下面和千锋广州小编一起来看看吧!一般来说,Java的程序开发包括三个步骤:编写程序,编译程序,运行程序编写程序——Java源代码,.Java文件编译程序——Javac用来进...
- 厉害了!全靠经典之作-Java编程思想,把小白教的明明白白
-
今天我们来聊聊这本《Java编程思想》从我学习Java的经验来看,《ThinkinginJava》是讲解Java编程的最佳书籍! 这本书不仅详细地介绍Java语法、知识点、API类库使用,更...
- 一周热门
- 最近发表
- 标签列表
-
- grid 设置 (58)
- 移位运算 (48)
- not specified (45)
- patch补丁 (31)
- 导航栏 (58)
- context xml (46)
- scroll (43)
- dedecms模版 (53)
- c 视频教程下载 (33)
- listview排序 (33)
- firebug 使用 (31)
- characterencodingfilter (33)
- getmonth (34)
- hibernate教程 (31)
- label换行 (33)
- curlpost (31)
- android studio 3 0 (34)
- android应用开发 (31)
- html转js (35)
- 索引的作用 (33)
- css3 0 (31)
- checkedlistbox (34)
- localhost 8080 (32)
- 多态 (32)
- net开发 (31)