Python爬虫、数据分析与可视化:工具详解与案例实战
上QQ阅读APP看书,第一时间看更新

3.3.1 继承的语法和使用场景

Python语言的继承语法是在定义的类名后加一个括号,在括号里指定待继承的父类名。而且,在Python里,所有的类都是object类的子类。在如下的InheritanceDemo.py案例中,我们来看一下继承的基本用法。


01 # coding=utf-8
02 class Emp:
03     def __init__(self, name,salary):
04         self.name = name
05         self.salary=salary
06     def work(self):
07          print('Emp work')
08     def addSalary(self, number):
09         self.salary = self.salary + number
10     def printInfo(self):
11         print('name is:' + self.name + ' salary is:' + str(self.salary) )
12 class PythonDeveloper(Emp):
13     def work(self):
14          print('develop python')
15     def learnPython(self):
16         print(self.name + ' learn Python.')
17 pythonDev = PythonDeveloper('Peter',12000)
18 pythonDev.printInfo() # name is:Peter salary is:12000
19 pythonDev.learnPython() # Peter learn Python.
20 pythonDev.addSalary(5000)
21 pythonDev.printInfo() # name is:Peter salary is:17000
22 pythonDev.work() # develop python

在第2行里,我们定义了Emp类,在其中定义了若干方法。在第12行定义的PythonDeveloper类里,我们通过括号让它继承了Emp类。注意,在父类(也叫基类)Emp和子类(也叫派生类)PythonDeveloper里定义的方法都是公有的,没有出现私有方法。

在第17行里我们创建了PythonDeveloper类,虽然在这个类里没有定义__init__方法,但它的父类里有,所以会使用父类的方法,在初始化pythonDev对象时,给name和salary属性赋值。

在第18行里,我们通过printInfo方法来确认初始化的效果,同样在子类PythonDeveloper里没有定义printInfo方法,这里还是调用父类的printInfo方法。在第19行调用的learnPython方法只存在于子类,所以毫无疑问。

第20行里调用的addSalary方法同样只存在于父类,所以调用的是父类Emp里的方法,而第22行的work方法在父类和子类里都有定义,根据继承语法里的覆盖原则,是调用子类里的,从该行的输出结果能验证这一点。

讲完了继承的语法,我们来归纳一下继承的使用要点:

第一,一般会把通用性的方法定义成公有方法,并只在父类里定义,比如这里的printInfo和addSalary方法。这样做的好处是在Emp的所有子类里都无须再重复编写。

第二,如果子类有针对本身的特殊方法,可以只定义在子类里。比如这里的learnPython方法只在PythonDeveloper类里适用,所以不能定义在父类里。

第三,如果通用性的方法在子类里有必要做调整,那么可以在子类里覆盖掉父类里的,比如这里的work方法就属于覆盖。

第四,也是最重要的一点,在设计父类和子类关系时,一定要有逻辑从属关系,比如“Python开发人员”从属于“员工”。否则,一定不能为了贪图方便而定义成父类和子类关系。