本文来自异想之旅公开发布的Python教程,原文地址:https://www.yuque.com/yxzl/python
类的继承
在前面的示例中,我们一直在使用Student
这个类。现在我们的需求升级了,不但需要在Student
中加入更多的属性和方法,还需要新增一个Teacher
类。按照之前的思路,我们可以这么书写:
class Student:
name = ''
age = 0
gender = ''
grade = 1
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_hello(self):
print('Hello!')
def introduction(self):
print('Hello, I am student', self.name)
class Teacher:
name = ''
age = 0
gender = ''
subject = ''
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_hello(self):
print('Hello!')
def introduction(self):
print('Hello, I am teacher', self.name)
我们发现,这两个类有着许多十分相似的地方:name``age``gender
三个相容的属性,__init__``say_hello
两个相同的方法,以及两个相似的introduction
方法。
我们考虑定义一个类People
,它将实现Student
和Teacher
共有的部分:
class Person:
name = ''
age = 0
gender = ''
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_hello(self):
print('Hello!')
class Student(Person):
grade = 1
def introduction(self):
print('Hello, I am student', self.name)
class Teacher(Person):
subject = ''
def introduction(self):
print('Hello, I am teacher', self.name)
看,将公共部分抽离后代码简短了一些,也变得更加直观了。现在我们希望我们在定义Student
和Teacher
时可以直接将People
的属性和方法也“据为己有”——即继承Person
已有的属性和方法,加上自己新增的,成为一个新的类。
我们在后面跟上一个括号,括号中写上要被继承的类。这一过程便被称为类的继承。Person
被称作Student
和Teacher
的父类,而Student
和Teacher
分别为Person
的子类。一个类的子类和父类都可以有多个。
在上面的代码后面执行这段代码,会得到这样的输出:
student = Student('小明', 10, '男')
student.say_hello() # Hello
student.introduction() # Hello, I am student 小明
teacher = Teacher('小红', 20, '女')
teacher.say_hello() # Hello
teacher.introduction() # Hello, I am teacher 小红
方法重写
现在要对Teacher
类的say_hello
方法进行更改:将输出的内容改为'Hello students!'
。
我们发现,这样一来Teacher
中的say_hello
方法和Student
中不一样了,而继承的部分一定是统一的才行。我们要将Person
中的say_hello
方法重新放回两个类中去分别定义吗?
自然,对于这个只有Teacher
和Student
两个类的示例,这样写也是可以的,但是假设我们还有Worker
等等一些其它的、也同时都继承自Person
的类,这样操作就太麻烦了。我们可以对类的方法进行重写。
class Person:
name = ''
age = 0
gender = ''
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_hello(self):
print('Hello!')
class Student(Person):
grade = 1
def introduction(self):
print('Hello, I am student', self.name)
class Teacher(Person):
subject = ''
def say_hello(self):
print('Hello students!')
def introduction(self):
print('Hello, I am teacher', self.name)
student = Student('小明', 10, '男')
student.say_hello() # Hello
student.introduction() # Hello, I am student 小明
teacher = Teacher('小红', 20, '女')
teacher.say_hello() # Hello students!
teacher.introduction() # Hello, I am teacher 小红
我们在子类Teahcer
中定义了一个和父类中方法重名的方法,Python 会自动使用子类中的定义而抛弃父类中的定义。
super()
基本用例
一个类可以通过 super()
调用其继承的类的函数:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, grade):
self.grade = grade
super().__init__(name, age)
高级使用
super()
可以传入两个参数,分别代表从哪个类向后找和传入的 self
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
class Student(Person):
def __init__(self, name, age, grade):
self.grade = grade
super().__init__(name, age)
# 上面一行语句等价于
super(Student, self).__init__(name, age)
比如我们有Person
继承Animal
,Student
继承Person
,想要在Student
里调用Animal
的函数,可以如下使用:
class Animal:
def __init__(self, age):
self.age = age
class Person(Animal):
def __init__(self, name):
self.name = name
class Student(Person):
def __init__(self, name, age, grade):
self.grade = grade
super(Student, self).__init__(name)
super(Person, self).__init__(age)
# 当然,上面只是一个演示,实际上这个例子应该这样写:
class Animal:
def __init__(self, age):
self.age = age
class Person(Animal):
def __init__(self, name, age):
self.name = name
super().__init__(age)
class Student(Person):
def __init__(self, name, age, grade):
self.grade = grade
super().__init__(name, age)
super
的全局使用
除了类的方法内部,在 Python 代码的任意位置都可以调用super()
函数。只不过,在方法之外的位置使用必须完整传递两个参数:
class People:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say_hello(self):
print('Hello!')
class Teacher(People):
subject = ''
def say_hello(self):
print('Hello students!')
teacher = Teacher('小红', 20, '女')
teacher.say_hello() # Hello students!
super(Teacher, teacher).say_hello() # Hello!