介绍
介绍
之前我们跟着福哥完成了“做个搜索引擎”项目的前半部分“网页蜘蛛”的程序的编写,童鞋们可以看到福哥将网页蜘蛛的功能封装成为了一个Spider对象,而不是简简单单的写一些函数,更不是直接码代码堆逻辑。大家可以发现在网页蜘蛛的“主程序”里面的代码非常简单,很清爽,很干净,这就是对象编程的优势,我们可以将功能的实现和业务的设计分离开来,在功能代码里只关注功能实现,在业务设计代码里只考虑业务设计,这是对象编程的思维带来的好处,程序员需要培养自己这个思维。
今天我们来学习一下Python语言里面的有个对象编程的一些高级语法,这些内容包括构造函数、析构函数、对象继承、方法重载,掌握这些技巧可以帮助我们设计出更加优美的对象,编写出更加漂亮的代码。
构造函数(Construct)
构造函数就是一个对象在初始化的时候自动被调用的一个函数,我们可以在这个函数里进行对象属性初始化的操作,也可以通过这个函数传递默认参数给我们的对象
python的构造函数使用了特殊的函数名称,即:__init__,使用这个名称定义的对象方法就会被作为对象构造函数使用
示例
可以看到,我们通过构造函数传递了id和name到对象TFMember里,并且将它们赋值给对象属性mId和mName
class TFMember: mId = None mName = None def __init__(self, id, name): self.mId = id self.mName = name def dump(self): print ("(" + str(self.mId) + ") " + self.mName) fuge = TFMember(168, "福哥") fuge.dump()
析构函数(Destruct)
析构函数就是一个在对象不再使用的时候(被释放资源之前)自动调用的一个函数,我们可以在这个函数里面关闭一些需要手动释放资源的句柄,例如:pymysql、elasticsearch等等
python的析构函数使用了特殊的函数名称,即:__del__,使用这个名称定义的对象方法就会被作为对象析构函数使用
示例
我们建立了析构函数,在里面打印了一句话,运行程序后,看到这句话的时候证明对象实例fuge就要被释放资源了
class TFMember: mId = None mName = None def __init__(self, id, name): self.mId = id self.mName = name def dump(self): print ("(" + str(self.mId) + ") " + self.mName) def __del__(self): print ("object TFMember for " + str(self.mId) + " is destroy") fuge = TFMember(168, "福哥") fuge.dump()
对象继承(Extends)
对象继承和我们理解的人类的继承很相似,儿子继承了父亲的DNA,那么儿子会从长相、性格、肤色、智力等等很多方面接近他的父亲,而子对象继承了父对象,那么子对象会拥有父对象的全部属性和方法
示例
我们建立了TFManager对象,这个对象继承了TFMember对象,所以TFManager的实例fuge也会拥有dump方法,也会拥有mId和mName属性
class TFMember: mId = None mName = None def __init__(self, id, name): self.mId = id self.mName = name def dump(self): print ("(" + str(self.mId) + ") " + self.mName) def __del__(self): print ("object TFMember for " + str(self.mId) + " is destroy") class TFManager(TFMember): mRank = 0 def __init__(self, id, name, rank): self.mId = id self.mName = name self.mRank = rank def __del__(self): print ("object TFManager for " + str(self.mId) + " is destroy") fuge = TFManager(168, "福哥", 8) fuge.dump()
大家可以看到虽然我们在TFMember和TFManager两个对象里都设置了构造函数和析构函数,但是最后生效的只是TFManager这个对象的构造函数和析构函数
方法重载(Override)
方法重载的意思就是基于对象继承之上的,比方说:一对父子都去做一道西红柿炒鸡蛋,两人都比较喜欢甜口味,但是儿子可能还会放一点盐,这点和父亲不一样。也就是说,儿子的某些能力或者行为与父亲不会完全一样,这时候定义儿子的时候就需要重新定义这种能力或者行为,这种做法在对象编程里叫做方法重载
python的对象方法的重载很自由,只要子对象的方法名称和父对象一样,无所谓函数是否一样都没关系,这样子对象的这个方法就会覆盖父对象的同名方法了
示例1
可以看到我们在TFManager里也定义了dump这个方法,且改变了方法的参数和实现,在fuge这个实例下运行后会发现实现完全是TFManager的逻辑了
class TFMember: mId = None mName = None def __init__(self, id, name): self.mId = id self.mName = name def dump(self): print ("(" + str(self.mId) + ") " + self.mName) def __del__(self): print ("object TFMember for " + str(self.mId) + " is destroy") class TFManager(TFMember): mRank = 0 def __init__(self, id, name, rank): self.mId = id self.mName = name self.mRank = rank def dump(self, type): if type == 1: print ("{" + str(self.mId) + "} " + self.mName) elif type == 2: print ("[" + str(self.mId) + "] " + self.mName) else: print ("(" + str(self.mId) + ") " + self.mName) def __del__(self): print ("object TFManager for " + str(self.mId) + " is destroy") fuge = TFManager(168, "福哥", 8) fuge.dump(1) fuge.dump(2) fuge.dump(3)
示例2
现在我们把TFManager的构造函数和析构函数都去掉了,会发现析构函数又变成了TFMember的实现逻辑了,这说明了在子对象里定义构造函数和析构函数也会重载父对象的构造函数和析构函数
class TFMember: mId = None mName = None def __init__(self, id, name): self.mId = id self.mName = name def dump(self): print ("(" + str(self.mId) + ") " + self.mName) def __del__(self): print ("object TFMember for " + str(self.mId) + " is destroy") class TFManager(TFMember): mRank = 0 def dump(self, type): if type == 1: print ("{" + str(self.mId) + "} " + self.mName) elif type == 2: print ("[" + str(self.mId) + "] " + self.mName) else: print ("(" + str(self.mId) + ") " + self.mName) fuge = TFManager(168, "福哥") fuge.dump(1) fuge.dump(2) fuge.dump(3)
总结
好了,今天童鞋们跟着福哥学习了python语言的对象编程基础知识:构造函数、析构函数、对象继承、方法重载。掌握了这些技巧之后,大家就可以设计出更为复杂,更为庞大的系统了。对象编程水平的提高是一个漫长的过程,需要在不断的项目开发过程中积累经验,需要在不断是实践当中总结教训,才能一步一步地成为大师的。