面向对象_new
2023-04-08 15:29:20 5 举报
AI智能生成
登录查看完整内容
python_面向对象
作者其他创作
大纲/内容
当两个类中有相同或相似的静态变量或绑定方法时,使用继承可以减少代码的重用,提高代码可读性,规范编程模式
场景
class A: passclass B(A):pass
class 子类(父类):pass
python3中所有类都继承objdec类
object类
单继承
C类继承A类和B类,享有A类和B类中的成员
多继承
语法
子类对象在调用方式时,只会执行子类自己的方法;
如果既要执行子类中的同名方法,又要执行父类中的同名方法,可在子类方法中主动调用父类同名方法:父类名.方法名(self)
1.子类重写父类中的同名方法
子类重写__init__方法,先调用父类的__init__方法来初始化共有属性,再在子类自己的init方法中初始化子类独有的属性(派生属性)
2.子类添加自己独有的属性(派生属性)
方法重写
1.子类对象,如果去调用方法,永远优先调自己的
2.如果子类自己有,用子类自己的
3.子类没有,用父类的
4.如果子类自己有,还想用父类的:直接在子类中调用父类的方法:父类名.方法名(self)
一个类有多个父类,在调用父类方法的时候,按照继承顺序,先继承的就先寻找
父类和子类方法选择
语法:
判断一个类是不是继承某一个父类
用途
type函数只能判断一个对象是不是某个类型;不能判断一个对象是否继承自某个父类
instance既可以判断对象是否属于某个类,也可以判断对象是否继承自某个父类
instance与type的区别
类中的方法,通过类名调用,就是函数
FunctionType: 函数
类中的方法通过对象调用,就是方法
MethodType: 方法
绑定方法和普通函数(了解)
在python3中都是新式类
在python2中默认是经典类
python2解释器,在类定义时主动继承object类,就会变成新式类
经典类和新式类
无论是经典类还是新式类,单继承都是深度优先
单继承:深度优先
经典类:深度优先
简单多继承内存图
小乌龟模型
新式类:广度优先
merge规则
理解即可,重点记住类名.mro方法,查看类的继承顺序
C3算法
类的继承顺序
定义:规范子类必须实现父类的同名方法,方便在子类中提供统一接口;记住:所有类都必须继承object类,如果见到了抽象类,一定要在子类中实现同名方法.
方式一:在父类成员方法中主动raise异常,在子类调用同名方法时抛异常(raise NotImplementedError(message))
方式二:通过导入abc模块下的ABCMeta类、abstractmethod函数实现;缺点:依赖第三方模块;优点:强约束,子类如果未重写父类中被abstractmethod装饰的方法,子类在实例化的时候就会报错
抽象类(软件开发规范)
队列(queue): 先进先出
栈(stack): 先进后出
定义:
通过继承方式实现队列和栈
队列和栈
super().父类属性名
1.访问父类属性
super().方法名(形参)
2.调用父类成员方法
注意:在py2的新式类中,super方法必须主动传当前子类的类名和self
2.在多继承中,super是按照mro顺序来寻找当前类的下一类
还是不太懂,实践出真知
super在单继承和多继承中的区别
super关键字
继承
把属性和方法封装到类中,类外不能直接调用了,要通过类的名字来调用
1.广义上的封装
类中的成员(静态变量、实例变量、绑定方法)私有化,只能在本类内部使用
2.狭义上的封装
3.封装实际就是java中用private修饰的成员,如果想对外提供访问或修改的入口,可根据需求对外提供私有成员的getter/setter方法;
1.定义
__静态变量名
1.私有化静态变量
2.私有化实例变量
__绑定方法
3.私有化绑定方法
2.私有化类的成员
1.成员私有化之后,都默认在私有成员前面加了: _类名__私有成员,这样类外在直接访问 ‘__私有成员’ 时,就会提示属性或方法不存在;可通过:对象名.__dict__ / 类名.__dict__ 查看私有成员
2.成员私有化之后,在类内调用时,会自动在私有成员前面补充上 '_类名',所以私有成员可以在类内访问
注意:类的成员私有化后,只能在本类中使用,类外和子类都不能使用
3.类成员私有化后不能从类的外部调用的原因?
公共的: 类内、类外、父类、子类
1.public
私有的:只有本类内部可以访问
2.private
py支持的封装级别
封装
1.一个类表现出来的多种状态,实际上是通过继承来完成的。父类具有子类类型的多种形态(多个子类继承同一个父类)
2.在python中处处是多态,因为python定义成员时没有强制定义类型
定义
1.结合isinstance方法判断一个对象是不是属于某个父类,如果是的话,就可以调用这个父类中的成员
2.通过多态对外提供归一化设计接口,在接口内部利用多态实例化子类并调用子类方法
多态
# 归一化设计 # class A: # def 同名功能(self):pass # class B: # def 同名功能(self):pass # # def 函数名(obj): # obj.同名功能()
设计思路:对外提供统一的接口供第三方使用,当需求变更时,不改变第三方使用者的调用方式
1.父类约束子类实现同名pay方法
2.对外提供统一的支付接口;根据支付方式,实例化不同的对象
支付场景:
继承中的归一化设计
三大特性
1.被装饰的方法,不能有参数
2.被装饰的方法可以通过类名/对象名.的方式调用,伪装成类的属性
3.被装饰方法可与私有属性搭配使用,方便类外对私有属性的查询、修改、删除
@propertydef 绑定方法(self):pass
@方法名.setter
@方法名.getter
@方法名.deleter
4.property装饰的成员方法,添加查询修改删除装饰器,以间接修改类中私有成员
property
classmethod
staticmethod
类的3个装饰器用法
反射:就是用字符串数据类型的名字,来操作这个名字对应的函数、实例变量、绑定方法、等各种方法
sys.modules['__main__'] : 当前文件(脚本)
sys.modules
反射__obj中的与name名字相同的成员
3. callable(__obj: object)
反射三大器demo
反射三大器
1.反射模块(导入的其他模块)中的内容
2.反射当前文件(脚本)中的内容
3.反射类中成员(静态成员或静态方法)
4.反射对象的属性或绑定方法
反射的应用场景
1.抽象类_重写父类pay方法
2.利用反射对外提供统一支付接口
反射的例子(归一化设计接口)
反射
定义:类是具有相同属性和行为的一类事物
成员变量
成员方法
类的命名空间:类在加载时会在呢库存中开辟一块内存空间,存储类中定义的所有成员
1.成员变量/静态变量
默认带有self参数(指向 对象的内存地址)
__init__ 方法:类实例化时自动调用,
其他成员方法,通过对象调用
对象.成员方法() # 相当于: 类名.成员方法(对象)
2.成员方法
类中的成员
类名.静态成员
访问类中的成员
类名.静态成员 = 修改后的值
修改类的静态成员
类名.变量名 = 初始值
给类增加新的静态成员
1.如果一个变量,是所有对象共享的值,那么这个变量应该定义成静态变量
2.所有和静态变量相关的增删改查,都使用类名来处理
使用场景
类的静态成员
返回一个字典,包含类的所有成员信息
类名.__dict__
类
给类中的所有属性填上具体的值就是一个对象或者实例
对象/实例
实例 = 类名(属性..)
self.属性名/方法名
实例变量
实例化
类中的成语变量归该类的所有对象共有
a.类的成员变量(静态变量)
其他成员方法: 类中具有的行为
b.成员方法
1.类加载时,在内存中开辟一块属于类的空间
a.该空间通过类指针,指向类本身的空间
b.调用 __init__方法,把属于对象的内存地址传递给 __init__ 方法的形参self
c. __init__ 方法把实例化传递的实参存储在self空间里 -- 对象的初始化
d.init方法的形参self所指向的内存地址会作为返回值,返回给实例对象
2.开辟一块属于self的空间
实例化过程
通过对象名.属性的方式实现增删改查
实例变量的增删改
对象.静态变量可以访问类的静态成员变量, 但不能进行赋值操作,否则就会在对象自己的空间中创建和静态变量同名的实例变量
对象.静态变量
注意点:
\"\"\"实现一个类,能够自动统计这个类实例化了多少个对象\"\"\"class A(): \"\"\" 统计类实例化次数 \"\"\" Count = 0 def __init__(self): A.Count += 1 # 每个实例对象都共享同一个静态成员变量Countfor i in range(10): A()print(A.Count) # 10
统计类被实例化次数
实例(对象)属性
返回一个字典,包含对象的所有属性和值
对象名.__dict__
一个类的对象时另一个类对象的属性
例如:班级和课程类,班级实例对象中包含课程类的属性
场景:
通过修改某一个对象实例的属性,就可以批量修改所有使用该对象实例作为属性的实例对象
优点
class Student: \"\"\" 学生类 \"\"\
class Clas: \"\"\" 班级类 \"\"\
class Course(): \"\"\" 课程类 \"\"\
# 练习 :# 对象变成了一个属性# 班级类 # 包含一个属性 - 课程# 课程 # 课程名称 # 周期 # 价格# 创建两个班级 linux57# 创建两个班级 python22# 查看linux57期的班级所学课程的价格# 查看python22期的班级所学课程的周期
案例:
对象的组合问题
对象和类内容回顾
对象
1.假设你想要一个类的某个属性是各自对象自己的,那么把它定义在__init__方法中
2.假设你想要一个类的摸个属性让所有对象共享,那么把它定义成静态变量
命名空间总结:
1.对象名.的方式给实例对象添加属性
2.类中静态成员指向一块空间,对象修改静态变量值,此时所有对象都会访问修改后的值
3.对象空间有的属性,只改对象自己的
4.类中存在重名成员时,后定义的成员会覆盖先定义的成员
案例1:本类中没有在父类中找
案例2:在子类中调用父类成员方法
案例3:同案例2
案例4:子类对象修改本类中的静态成员变量
案例5:子类对象修改父类中的静态成员变量
案例6:子类对象修改对象自己的属性
案例7:对象在找成员变量或成员方法时,遇到self总是先回子类对象或子类中找,找不到在去父类中找
类和对象的命名空间
面向对象初识
dir(对象/类型):以列表形式返回当前类中有哪些方法
定义:不通过继承来实现一个类属于某个类,这个类就是鸭子类型例如:只要实现了__iter__和__next__方法的类,就是迭代器类
代码实例:
查看子类继承的第一个父类,所有类默认继承object
__base__
查看子类继承的所有父类
__bases__
查看多想的所有属性
对象.__dict__
包含调用类的模块和成员变量、成员方法
查看类的所有成员
__dict__
返回函数名
函数名.__name__
返回类名
类名.__name__
__name__
返回所属类型,默认都是: <class 'type'>
__class__
返回当前类的所在的模块名
__module__
返回类或函数中的文档注释
类名.__doc__
函数名.__doc__
__doc__
计算可迭代类型长度
__len__
可迭代
__iter__
取迭代器的元素
__next__
常见鸭子类型
鸭子类型(魔术方法)
pickle支持的序列化类型:支持Python所有的数据类型包括实例化对象
1.封装pickle模块:实现多次写入,多次读取
2.封装json模块:实现多次写入,多次读取
抽象类约束子类
反射实现归一化设计接口
抽象类+反射归一化设计封装json和pickle类
pickle\\json实现多次写多次读
https://www.cnblogs.com/Eva-J/articles/9235899.html
选课系统需求
面向对象
0 条评论
回复 删除
下一页