学习python继承的一些想法与经验。
在学习python的面向对象时,始终参照的是c++的面向对象机制。
相对而言,python的面向对象确实更简单一些。
基础:
整数也被作为对象。前面就看到过,说所有的东西都是对象,包括函数。
属于一个对象或类的变量被称为域——这个名称有点奇怪,c++叫成员。
域分为两种,分别属于对象和属于类——其实就是成员和静态成员。
Self指针:相当于c++中的this。
python中,可以把类当成另一种形式的函数,self告诉python使用哪个对象的成员变量。
python中,类成员函数和全局函数相同名都只存在一个。后写的函数会覆盖先前的,不存在函数重载。
__init__方法
类的构造函数是__init__方法,它在创建类时调用。
它并不是必须的,可以没有。
成员变量和类的变量,方法
类变量的定义:缩进和方法的缩进相同。引用时,需要使用class.变量名的方式。
成员变量可以在类内的任意地方定义。在成员函数内定义的话,self.xxx=... 就可以了。但在逻辑上要保证使用这个成员变量时,它已经定义。
在类内,成员函数之外定义的变量是类成员。所有这个类的对象都可以调用。
析构函数
__del__方法相当于他的析构函数,在对象被销毁时调用。
私有函数
如果成员函数或成员变量以双下划线__开始,表示private。不以双下划线开始命名的是公胡成员。python中没有类的保护成员。
继承:
继承时成员特性:
对于类的成员,在子类中可以通过父类.变量名或者子类.变量名来访问,是相同的。
对于对象的成员,在子类中通过self.变量名来访问。访问不属于这个类的私有成员“_classname__method”或“_classname__variable”
继承时方法的特性:
生成子类的构造函数时,不会自动调用父类的构造函数,你必须手动调用它。同时,在对象释放时,同样要手动调用析构函数。
子类的构造函数和析构函数可以不定义,如果不定义的话,这会调用基类的构造和析构函数。
Python不存在动态绑定和静态绑定。这一点和c++不同。
如果基类有一个public函数,子类中重新定义一个和他名称相同,子类覆盖父类函数,python中没有函数重载,一个函数名只能对应一个函数。
这种继承模型确实非常简单。
特殊方法:
下面介绍下我写python类继承遇到的奇葩问题:
python继承的例子。
class A(object): def tell(self): print 'A tell' self.say() def say(self): print 'A say' self.__work() def __work(self): # private print 'A work' class B(A): def tell(self): print 'tB tell' self.say() super(B,self).say() A.say(self) def say(self): print 'tB say' self.__work() def __work(self): # private print 'tB work' self.__run() def __run(self): # private print 'tB run' b = B() b.tell()
获得的结果:
B tell
B say
B work
B run
A say
A work
A say
A work
再把例子中的私有函数,全变成public的:
class A(object): def tell(self): print 'A tell' self.say() def say(self): print 'A say' self.work() def work(self): # public print 'A work' class B(A): def tell(self): print 'tB tell' self.say() super(B,self).say() A.say(self) def say(self): print 'tB say' self.work() def work(self): # public print 'tB work' self.run() def run(self): # public print 'tB run' b = B() b.tell()
获得结果:
B tell
B say
B work
B run
A say
B work
B run
A say
B work
B run
从以上例子可知,想用python在父类调用子类的override函数,最好把相关函数全变为公有。
python适合做胶水,不适合做零件。涉及到复杂设计及计算效率的代码,还得用C++。