目录
继承方法
在上一节中,我们已经学会如何创建一个类,并赋予属性和方法最后实例化到对象上。我们可以自由定义一个类,当我们想定义的一个类和先前已经定义过的类高度相似,重新定义一个新类并逐个赋予属性和方法就显得很麻烦(很可能一些属性和方法在另一个相似的类中已经定义过了),此时就可以用到类的继承。
继承后的产生的新类叫做子类,被继承的类叫做父类。
比如,要定义一个打工人的新类,与我们上一节定义过的人类高度相似,都具有年龄和性别属性,但多了一些方法,比如打工和摸鱼。那就可以对人类进行继承,继承类的语法为:
class Newclass(Oldclass):
<定义属性和方法>
就上一节的例子继续:
class Human: #创建人这个类
def __init__(self, age, gender): #初始化方法
self.age = age #定义人的属性:年龄和性别
self.gender = gender
def say_Hi(self): #定义打招呼的方法
print("Hi, I'm a", self.gender,", and I'm", self.age, "years old!")
class Worker(Human): #类的继承
pass
Jeff = Worker(25, 'man')
Jeff.say_Hi() #让打工人Jeff给大家打个招呼
在代码中用语句class Worker(Human): 继承了Human这个类,创建了一个名为Worker的新类。下一行用pass表示仅进行继承不进行其他操作。
接下来将继承类实例化,创建了一个名为Jeff的对象,可见继承类的对象可以不需要定义就可以直接使用父类的方法say_Hi()。
代码的运行结果为:
但是还没结束,既然进行了类的继承,就需要定义新的属性和方法,否则继承将无意义。在这里我们赋予打工人这个新类"职位"的新属性,以及"打工"这个新方法,接下来需要对代码稍作修改:
class Worker(Human): #类的继承
def __init__(self, age, gender, position): #继承类的构造函数
Human.__init__(self, age, gender) #调用父类的构造函数
self.position = position #赋予新属性
def gowork(self): #定义新方法
print("I'm working now!")
在这里为了方便,调用了父类的构造函数来初始化age和gender属性。
由于增加了新属性,在实例化的时候需要多传递一个"职位"的参数。并写入了一个新方法,让打工人去打工。接下来继续创建一个对象,并调用他的方法:
Alice = Worker(34, 'woman', 'manager')
Alice.say_Hi()
Alice.gowork()
代码运行结果为:
由此可见,通过类的继承,子类可以继承父类的属性和方法并正常使用,此外也可以再此基础上定义新的属性和方法。
类的覆写
有些情况下,父类的方法不能满足子类的要求,就要对父类的方法进行覆写。比如在上面Human这个父类中的say_Hi()方法,对于子类Worker来说,想在调用say_Hi()方法打招呼的时候加上自己的职位(position),就要对父类的方法进行修改。
修改方式为在子类下直接对该方法进行修改即可:
class Worker(Human): #类的继承
def __init__(self, age, gender, position): #继承类的构造函数
Human.__init__(self, age, gender) #调用父类的构造函数
self.position = position #赋予新属性
def gowork(self): #定义新方法
print("I'm working now!")
def say_Hi(self): #重写父类方法
print("Hi, I'm a", self.gender,", and I'm", self.age, "years old!", "\nMy position is a", self.position, "!")
接下来重新调用say_Hi()方法:
Alice = Worker(34, 'woman', 'manager')
Alice.say_Hi()
运行结果为:
在这里使用了"\n"换行符,此外有一个小小的bug忽略了职位导致冠词a/an的变化,不过无伤大雅。
多重继承
Python同样支持多个类的继承,一次性继承有限个类。属性和方法为父类的总和(在没有重复属性和方法的前提下)。多重继承的语法为:
class Newclass(class1, class2, class3...)
<定义属性和方法>
多重继承是一个很强大且有趣的功能,可以像积木一样把多个类拼接到一起。
接下来创建两个超能力类,具有lazer_eye(激光眼)和fly(飞翔)方法
class Superpower1:
def lazer_eye(self):
print('Lazer shooting!')
class Superpower2:
def fly(self):
print('Flying!')
接下来创建一个新类直接继承Human, Superpower1, Superpower2三个父类,将其命名为Superhero,具有超能力的人就是超级英雄,很形象。
具有激光眼和飞翔的超能力很容易想到黑袍纠察队的祖国人,所以创建这个对象,并让他展示一下超能力:
class Superhero(Human, Superpower1, Superpower2): #创建超级英雄类
pass
Homelander = Superhero('unknown', 'man') #实例化对象:祖国人
Homelander.lazer_eye() #发射激光眼!
Homelander.fly() #飞翔!
运行结果为:
进行多重继承后的子类,可以拥有父类所有的属性和方法。但如果多个父类以不同的形式实现了一种方法(有同名方法或属性),那么需要注意在声明子类时父类的排列顺序,位于前面的类的方法会覆盖后面的类方法。
class Newclass(class1, class2, class3...)
(class1会覆盖掉class2或class3的同名方法)
不过对于多种大型类,最好避免使用多重继承,因为可能会带来一些奇怪的问题,方法和属性发生重合在此情况下很容易发生。