在Python面向对象编程中,继承是一种让类之间共享属性和方法的机制。通过继承,我们可以让“子类”自动拥有“父类(基类)”定义的属性和方法,并在必要时进行拓展或重写,让代码更加灵活、复用性更好。
1. 创建父类(基类)
假设我们先定义一个基础类,用于描述一个人的姓名:
class Person:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname
def printname(self):
print(self.firstname, self.lastname)
# 创建Person类的对象并调用方法
p1 = Person("Li", "Lei")
p1.printname()
# 输出: Li Lei
这里Person
类拥有firstname
和lastname
属性,以及打印姓名的方法printname()
。
2. 创建子类(派生类),继承父类
现在我们想让学生(Student)也具有和Person相同的属性与方法,那么可以在定义Student类时写成这样:
class Student(Person):
pass
这意味着Student
类继承了Person
类所有的属性和方法。pass
关键词表示暂时不添加任何新内容。
# 试着创建Student对象
s1 = Student("Han", "Meimei")
s1.printname()
# 输出: Han Meimei
可以看到,Student类并没显式定义printname
方法,但仍能用,因为它继承自Person。
3. 在子类添加__init__()并保留父类功能
如果需要在子类初始化时做更多操作,就要在子类中定义自己的__init__()
。但这会覆盖掉父类的初始化方法,所以我们必须显式调用父类__init__()
:
class Student(Person):
def __init__(self, fname, lname):
# 显式调用父类的__init__来保留原功能
Person.__init__(self, fname, lname)
# 或者使用super()函数
# super().__init__(fname, lname)
# 在此添加子类自己的属性、初始化操作
self.graduationyear = 2025
这样在创建Student
对象时,不仅继承了Person
的firstname
和lastname
初始化逻辑,还新增了一个graduationyear
。
super()函数会自动帮我们找到父类并调用它的方法,无需写Person.__init__
。
4. 在子类中添加属性或方法
子类可以定义自己的属性或方法,甚至可以覆盖父类已有的方法:
class Student(Person):
def __init__(self, fname, lname, year):
super().__init__(fname, lname)
self.graduationyear = year
def welcome(self):
print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)
s2 = Student("Tina", "Wu", 2023)
s2.printname() # 来自父类
s2.welcome() # 来自子类
5. 覆盖父类方法(方法重写)
当子类里定义了和父类同名的方法时,就相当于把父类的方法“覆盖”掉,这叫方法重写(override)。如果需要先执行父类的方法,再执行子类自己的逻辑,也可在子类方法里先调用super()
。
6. 总结
- 继承可以让子类拥有父类的属性和方法,实现代码重用。
- 子类定义__init__()时需要主动调用父类的
__init__()
来保留原始功能。 - super()函数能更加简洁地调用父类方法,推荐使用。
- 子类可在原功能基础上进行扩展或重写。
继承是Python面向对象编程的重要特性之一,运用得好可以让代码更易维护和扩展,避免重复编写相同逻辑。