对象
对象=属性+方法
调用:
面向对象的特征
封装:是一种信息隐蔽技术。
继承:子类自动共享父类之间数据和方法的机制。
多态:不同对象对同一方法响应不同的行动。
self
Python的self相当于C++中的this指针。
由同一个类可生成很多对象,
init(self)方法
该方法称作构造方法。体现在,只有实例化一个对象的时候,该方法在对象被创建的时候自动调用,也类似于C++的构造函数,可写作_init_(self,param1,param2,…)
公有与私有
>>>class Person:
name="小甲鱼"
>>>p=Person()
>>>p.name
'小甲鱼'
为了实现私有变量的特征,Python内部实现了一种叫做name mangling(名字改编,名字重整)的技术。
在Python中定义私有变量只需要在变量名或函数名前加上两个下划线,那么这个函数或者变量就会变成私有的了。
加双下划线以后在类外部就不能直接访问,而是需要通过内部引用该属性才能得到私有变量。
原因:Python把加双下划线的变量改名为了_类名_变量名。说明Python的私有机制实质上是伪私有,变量实质上是可以被调用的。
>>>p._Person_name
'小甲鱼'
继承
语法:class DerivedClassName(BaseClassName 父类):
……
注:被继承的类称为基类、父类、超类,继承者为子类。
值得注意的是,如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性,例如:
小例题:
假如有一个装有各种鱼类的鱼塘,其中包括鲨鱼、金鱼、鲤鱼、三文鱼,通过调用父子类的函数方法实现。
调用后:
此处在调用鲨鱼移动的时候程序报错,因为在鲨鱼子类定义的时候定义了与父类同名的函数导致父类的移动函数被覆盖,从而没有x的定义。
解决方法:
- 调用未绑定的父类方法
调用后:
- 使用super函数
调用以后同样有效。
好处:当有多重继承时,不用给定基类名字,只需更改class Shark()括号中的父类,super()函数即可自动查找。
多重继承
同时继承多个父类的属性和方法。
语法:class DerivedClassName(Base1,Base2,Base3父类):
……
但是多重继承容易导致代码混乱,所以应该避免使用。
组合
把类与实例化放到一个新类里面,即把旧类组合进去,不用继承,减少多重继承的风险;同时,把没有太大关系的、横向关系的几个类放到一起,实现多元化;而需要纵向关系的时候就需要用到多重继承了。
调用后:
类、类对象、实例对象
其中,class C为类,在定义以后也是一个类对象,因此在下方直接调用的时候能够生效。
其中的关系:
如果属性的名字和方法相同,属性会把方法覆盖掉,例如:
注:实例化是指令前方生成的一个结果赋值给一个变量,而该变量称为实例化对象。
相关的BIF(内置函数)
- issubclass(class,classinfo)
如果class是classinfo的一个子类就返回true。
但应注意,一个类被认为是自身的子类;classinfo可以是类对象(class)组成的元组,只要class与其中任何一个侯选类的子类相同,返回true;其他情况返回TypeError异常。
注:object是所有类的一个基类,亦即所有类无论是否写了基类,都默认继承了object。
- isinstance(object,classinfo)
检查一个实例对象是否属于一个类。class传入一个实例对象,classinfo传入一个类或元组。若第一个传入不是类,则永远返回False;若第二个参数不是类或者由类对象组成的元组,则会抛出TypeError异常。
访问对象属性的BIF
除了通过点操作符访问对象的属性,还可以有以下方法:
- hasattr(object,name)
attr=attribute:属性
作用:测定一个对象里面是否有指定的属性,第一个参数是对象,第二个参数是属性名,属性名要用表示字符串的双引号穿起来。
- getattr(object,name[,default])
作用:返回对象指定的属性值,如果指定的属性不存在同时设定了default参数,函数会返回default值,否则抛出异常。
- setattr(object,name,value)
设定对象中指定属性的值,如果指定属性不存在会新建一个新属性并给他赋值,其中name还要加一对单引号。
- delattr(object,name)
作用:删除对象中指定的属性,如果属性不存在,则抛出异常。
- property(fget=None,fset=None,fdel=None,doc=None)
作用:通过属性设置属性。