作为python的主要特征之一,面向对象无疑是非常重要的一部分,只有熟练掌握了继承、多态、公私有等问题,才能利用好类的属性。所以,本篇笔记用一篇来记录面向对象的有关知识。
一.面向对象概述
对于面向对象而言,实际上就是对于对象的建造和利用。由于面对的问题千奇百怪,Python提供的数据类型很难满足我们编程的全部要求,因此,我们需要自己创造一个符合我们使用的,可以自定义各类功能属性的数据类型,而这,就是类的主要诞生原因。而且,类也更加体现了封装的重要,其特殊的机制对于整体编程很有意义。
就像前文所述,类就相当于一个新数据类型,给创建的变量进行约束,而其中的功能被称作方法,属性也就是特征。而根据类之间不同的关系,也有了很多新的性质,及继承、多态等
类的语法格式为:
class 类名:
方法
属性
二.方法与属性
1.方法
方法是类中最主要的部分之一,其创建方法与函数极其相似,大部分的方法和变量的内置函数使用时一样,但对于一些特殊使用的方法,其具有特别的命名方法。
dir函数(类方法):
dir实际就是内置的意思,在编译过程中如若忘记变量的部分内置函数,可以使用dir查看。
注:这些__都是两个下划线!!!
这些dir函数如同C++中的构造函数,析构函数等拥有一样的功能。其前面需要使用@classmethod 声明。
定义语句:
class 类名 :@classmethoddef 类方法名 ( cls [, 形参列表 ]):方法体
实例对象方法:
即正常的、基础的方法编译方式:
def 方法名(self[,参数表]):
方法体
注:方法的第一个参数一般必须是self,表示调用此方法的变量。
对象调用时的方法为:对象.方法名([实参表])。但类调用时不能同对象调用一般,直接调用,因为未给self传递实参,因此想要调用实例对象时,必须手动提供实例。才能保证正常使用。
而在进行方法编译时,为了实现封装效果,保存一些不便示人的事务,还衍生了私有方法。
而私有方法的改造并卜复杂,与类方法类似,也是对方法名进行标注,即只在方法名前加__.
私有方法不允许对象直接调用,只能在方法中访问。
但实际上,并没有真正的私有情况,只是对名称进行了特殊处理从而使外界无法访问。
静态方法:
静态方法与类的实例对象无关,也不能使用类的属性。但可以被对象调用,在定义时需要使用@staticmethod声明
定义语句:
class 类名 :@staticmethoddef 静态方法名 ([ 形参列表 ]):方法体
运算符重载:
eg:
class Vector:def __init__(self,value):self.value = valuedef __add__( self, other ):he=[i+j for i,j in zip(self.value, other.value )]return(tuple(he))x= Vector((1,2,3))y= Vector((3,4,5))z=x+y注:这里的+就是使用了重载的运算符。
索引和分片重载:
函数调用:
__getitem__ :索引、分片;def __setitem__(self, index, value):self.data[index] = value__setitem_ _ :索引赋值;def __setitem__(self, index, value):self.data[index] = value__delitem__ :索引和分片删除。def __delitem__(self, index):del self.data[index]
__call__()方法:
2.属性
属性相当于类的特征,虽然有时候类不需要特征。
属性和C++中类的属性类似,可以便于理解。但属性的定义并不像C++一样裸定义。而是需要借助方法包含。
self.实例变量名=初始值
类内部用self.属性进行调用。外部由对象进行调用。
类对象属性:
实例对象属性和类属性的区别为:
实例对象属性的优先级要高于类属性,在调用属性时会优先查看是否有实例对象属性,再去看是否有类属性;同时,在初次调用前,类属性的地址都是同一个,在对象调用后,对象中会创建一个自己的类属性;同时,对象两种属性都可以直接调用,但类调用只能调用类属性,不能调用实例对象属性。
属性的动态修改:
直接用对象增加,修改实例属性都是可以的,但类属性不能增加。
私有属性:
与私有方法类似,表示一些不愿意让人看到的东西。
定义方式也是属性名前增加__。
对象无法调用私有属性,但方法中可以调用。
三.面向对象的特征
1.封装
封装是类最重要的一个特征,我们通常把隐藏的属性与方法实现细节的过程称为封装。
2.继承
就如同子继承父一样,类之间也有继承一说,一个类继承另一个类的所有的东西,也就是在原有的类的一个基础上去建立一个新的类,就叫做继承。原有的类叫父类(基类),新构造的叫子类(派生类)。
子类构建方法:class 子类名(父类名):
当一个子类只有一个父类时,其被称为单继承。当拥有多个父类时,就是多继承。
注:私有属性和私有方法无法继承,子类也无法访问
但在继承时,常会出现父类方法无法完全解决的情况,因此可以对父类方法进行重写:
当方法内容完全不一样时,可以使用覆盖的方式,用原方法名进行重写。但如果只是要扩容,就在新更改的方法中适时使用super.父类方法调用即可。
当多继承时,如果两个基类有相同名称的方法,那么会优先调用哪一个呢?
这时,计算机会遵循就近原则,先继承哪个就用哪个。
Tips:
新式类与旧式类:
新式类:在如今的python版本中,如果未使用继承机制,即无父类时,计算机会自动指派一个类做基类——object类。
旧式类则无。
为不影响多继承时就近原则出现问题,推荐显示继承object类。
object是一个基础的类,里面有一些简易的内置方法。可以使用dir()函数查看。
3.多态
多态即不同子类调用一个相同的父类方法,但产生不同的结果。
多态以继承和重写父类方法为基础。不影响类的基本构造。
多态的注意点:
在python中多态的意图和功能都和其他大部分语言相同,都是希望提供一个函数实现不同的功能。可python更简单,像在C++中实现多态还需要关键词,指针指向等多种条件指引以实现多态,在python中是默认以多态的思想进行指定,所以省去了指针和抽象类等工作。
4.其他
在进行对象的赋值时,常运用的是浅复制(浅拷贝),即都指向同一个地址。如果想复制对象,则需要运用以下方法:
切片操作: acc1[:] ;对象实例化: list(acc1);copy模块的copy() 函数: copy.copy(acc1)
像列表浅拷贝的情况,是要生成一个新列表,并把原列表中所有元素的引用全部拷贝到新列表中。
方法:
列表切片 :lists[ : ]copy模块的copy()方法 :copy.copy()
但在浅拷贝中,如果涉及可变对象的拷贝,则只会将引用拷贝过去,即改变新的值会影响旧的值。
因此,少数情况下,我们需要深拷贝:
copy.deepcopy(alist)
5.单例
大部分类是提供一个后续可以多次使用的模板,但单例则恰恰相反,其目的是让类创造的对象在系统中只有唯一一个实例。每一次执行方法类名等返回的地址相同。
其大多数的应用场景为:音乐播放,回收站,打印机等对象。
__new__方法:
当利用类名创建对象时,会使用new开辟空间给对象分配,然后将该对象的引用传递给__init__使用。因此,重写__new__的代码非常固定。
重写时,一定要return super().__new__(cls).
更多内容查看单例的专栏吧。
今天先到这。
END?