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开发人员”从属于“员工”。否则,一定不能为了贪图方便而定义成父类和子类关系。