1. 类的继承概述
类的继承是面向对象编程中的重要特性之一,该特性允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)中除构造方法以外的所有属性和方法,这些被继承的属性和方法被称为子类的成员。
类的继承通常是基于现有类的特定行为和用法来定义新类,这种方法避免了编写和组织重复代码的需要,从而提高代码的重用性和可维护性。
2. 单继承
2.1 基本语法
在Python中,使用如下语法定义一个类的继承关系:
class ChildClass(ParentClass):
pass
其中,ChildClass表示子类名,ParentClass表示父类名。在定义子类时,需要将父类名放在子类名后面的圆括号中,圆括号中的内容表示从父类继承的属性和方法。
2.2 实现继承
Python中的单继承是指一个子类只有一个父类,通过继承父类,子类可以直接使用父类的所有公共变量和函数。
例如,我们定义了一个名为Person的父类,在其基础上定义了一个名为Student的子类,子类通过继承父类,可以直接使用父类中的变量和方法:
class Person:
name = ""
age = 0
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello, my name is", self.name, "and I am", self.age, "years old.")
class Student(Person):
student_id = ""
def __init__(self, name, age, student_id):
super().__init__(name, age)
self.student_id = student_id
def study(self):
print(self.name, "is studying.")
在上述代码中,Student类继承了Person类,在子类中可以直接使用父类中定义的变量和函数,例如,在Student类的构造函数中,通过调用父类的构造函数初始化了父类中定义的变量name和age。
2.3 调用父类方法
子类也可以调用继承自父类的方法,例如:
class Student(Person):
student_id = ""
def __init__(self, name, age, student_id):
super().__init__(name, age)
self.student_id = student_id
def study(self):
print(self.name, "is studying.")
def say_hello(self):
super().say_hello()
print("My student ID is", self.student_id)
stu = Student("Tom", 18, "20210001")
stu.say_hello()
在上述代码中,子类Student重写了父类Person的say_hello()方法,在该方法中通过调用super().say_hello()语句调用父类中的say_hello()方法,同时添加了自己的输出内容,从而实现了对继承的方法的扩展。
3. 多继承
3.1 基本语法
除了单继承之外,Python还支持多继承,即一个子类可以同时继承多个父类,继承关系如下:
class ChildClass(ParentClass1, ParentClass2, ..., ParentClassN):
pass
其中,ChildClass表示子类名,ParentClass1、ParentClass2、...、ParentClassN为父类名,中间用逗号隔开。
3.2 方法解析顺序
当子类继承了多个父类时,子类在调用被多个父类定义的同名方法时,会按照一定的顺序进行解析,该顺序称为方法解析顺序(Method Resolution Order,简称MRO),MRO的计算方式是通过广度优先算法实现的,并且按照从左到右的顺序查找。
例如:
class ParentClass1:
def hello(self):
print("Hello from ParentClass1")
class ParentClass2:
def hello(self):
print("Hello from ParentClass2")
class ChildClass(ParentClass1, ParentClass2):
pass
child = ChildClass()
child.hello()
在上述代码中,子类ChildClass同时继承了ParentClass1和ParentClass2两个父类,且这两个父类都定义了hello()方法,此时调用child.hello()方法会按照从左到右的顺序查找,即先在ParentClass1中查找,找到hello()方法后便不再查找,因此会输出"Hello from ParentClass1"
此外,在子类中重写父类的同名方法,Python会优先调用子类中的方法,从而实现对父类方法的覆盖和扩展。
3.3 经典类和新式类
在Python 2.x版本中,存在两种类型的类分别是经典类和新式类。
经典类:继承自object类的类称为新式类,如果不继承自object类则称为经典类。如下:
class ParentClass: # 经典类
pass
class ChildClass(ParentClass): # 经典类
pass
class NewParentClass(object): # 新式类
pass
class NewChildClass(NewParentClass): # 新式类
pass
新式类:在Python3.x及之后的版本中,所有类都是新式类,在继承时不再有经典类的问题。
4. super函数
4.1 基本语法
super函数是Python中一种特殊的函数,用于调用父类中的方法。super函数的语法如下:
super([type[, object-or-type]])
其中,type表示当前类的类型(在Python 3中可以省略),object-or-type表示当前类的对象或类型。
4.2 使用super函数
在Python中,通过调用super函数可以调用父类中的方法,其特点在于无需指定父类的具体名称,而是根据当前类的类型和继承顺序自动确定所调用的父类方法。例如:
class A:
def hello(self):
print("Hello from A")
class B(A):
def hello(self):
super().hello()
print("Hello from B")
class C(A):
def hello(self):
super().hello()
print("Hello from C")
class D(B, C):
def hello(self):
super().hello()
print("Hello from D")
d = D()
d.hello()
在上述代码中,定义了四个类A、B、C和D,其中B、C类分别继承于父类A,最终子类D同时继承B、C类,并且重写了hello()方法,在子类D中的hello()方法中,通过super().hello()调用了B和C类的hello()方法,在每个类中,通过调用super().hello()方法,逐级向上调用了父类A的hello()方法,因此输出结果为:
Hello from A
Hello from C
Hello from B
Hello from D
5. 总结
类的继承是面向对象编程中重要的一个概念,能够将多个类中的重复代码提取出来,提高代码的重用性和可维护性。Python中的继承可以使用单继承和多继承实现,通过调用super函数可以方便地调用父类中的方法,并且在多继承时可以灵活地控制方法的调用顺序,从而实现对继承类的扩展和重写,提高程序的可扩展性。