Python继承机制:子类初始化、方法重写与属性组合详解

Chloe
Chloe
发布时间:2026-10-15| 4人浏览过
原创

本文深入解析Python中的类继承机制,涵盖单继承与多继承的查找顺序。重点讲解如何在子类中通过super()调用父类__init__以初始化属性,以及如何通过同名方法定义实现父类方法的重写。此外,还介绍了将复杂属性(如电池类)提取为独立类并作为子类属性的组合设计模式,帮助优化代码结构。

继承

在面向对象编程中,创建新类时往往不需要从零开始。若新类是现有类的特定变体,可采用继承机制。Python支持单继承与多继承两种形式。

当一个类继承另一个类时,它将自动获得父类的所有属性和方法。原类被称为父类(或超类),新类称为子类。子类不仅拥有父类的全部功能,还可定义独有的属性和方法,从而有效减少类之间的代码冗余。

如何确定子类所继承的父类?

具体实现方式如下所示:

class Parent_1:
    pass
class Parent_2:
    pass
class sub1(Parent_1):#单继承
    pass
#查看自己的父类
print(sub1.__bases__)
class sub2(Parent_1,Parent_2):#多继承
    pass
#查看自己的父类
print(sub2.__bases__)
(<class '__main__.Parent1'>,)
(<class '__main__.Parent1'>, <class '__main__.Parent2'>)

多继承的优缺点

优点在于子类可同时继承多个父类的属性,最大化代码复用率。缺点则是可能降低代码可读性,因一个子类对应多个父类,逻辑关系较为复杂。

属性与方法查找顺序:

查找路径为:对象实例 > 子类 > 父类 > 父类的父类。

具体示例如下:

class Fu():
    def f1(self):
        print('Fu.f1')
    def f2(self):
        print('Fu.f2')
        self.f1()#对象名.方法(),此时的self==objects
class son(Fu):
    def f1(self):
        print('son.f1')
objects=son()
objects.f2()

依据上述查找顺序,系统首先在对象实例的空间内查找方法f2;若未找到,则转向子类空间查找;最后才在父类空间中查找。

Foo.f2
Bar.f1

子类中的__init__方法

在基于现有类构建新类时,通常需要调用父类的__init__()方法。此举旨在初始化父类__init__中定义的所有属性,确保子类实例包含这些基础属性。

示例代码如下:

#定义一个父类Car,父类又名超类,名称super由此而来
class Car:
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0
    def get_descriptive_name(self):
        long_name=f"{self.year} {self.make} {self.model}"
        return  long_name.title()
    def read_odometer(self):
        print(f"this car has {self.odometer_reading} miles on it ")
    def update_odometer(self,mileage):
        if mileage>=self.odometer_reading:
            self.odometer_reading=mileage
        else:
            print("you can't roll back an odometer!")
    def increment_odometer(self,miles):
        self.odometer_reading+=miles
#定义一个子类ELectricCar,创建子类时,父类必须包含在当前的文件,父类必须位于子类的前面
class ELectricCar(Car):#定义子类时,必须在圆括号内指定父类的名称
   #方法__init__()接受创建Car实例所需的信息
    def __init__(self,make,model,year):
        print("__init__()方法被调用")
        #让python调用Car类的方法__init__(),让子类创建的实例包含父类这个方法中定义的所有属性
        super().__init__(make,model,year)#super是一个特殊函数,使我们能够调用父类的方法
my_tesla=ELectricCar('tesla','model s',2019)
print(my_tesla.make)
print(my_tesla.year)
print(my_tesla.model)
print(my_tesla.get_descriptive_name())
__init__()方法被调用
tesla
2019
model s
2019 Tesla Model S

上述代码旨在验证子类ELectricCar是否继承了父类Car的属性,但此时子类尚未定义其特有的属性和方法。

为子类定义专属属性和方法:

继承后,可在子类中添加区分其与父类差异的新属性和新方法。

以下代码添加了一个电动车特有的属性及描述该属性的方法:

沿用前述代码结构:

#定义一个父类Car,父类又名超类,名称super由此而来
class Car:
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0
    def get_descriptive_name(self):
        long_name=f"{self.year} {self.make} {self.model}"
        return  long_name.title()
    def read_odometer(self):
        print(f"this car has {self.odometer_reading} miles on it ")
    def update_odometer(self,mileage):
        if mileage>=self.odometer_reading:
            self.odometer_reading=mileage
        else:
            print("you can't roll back an odometer!")
    def increment_odometer(self,miles):
        self.odometer_reading+=miles
#定义一个子类ELectricCar,创建子类时,父类必须包含在当前的文件,父类必须位于子类的前面
class ELectricCar(Car):#定义子类时,必须在圆括号内指定父类的名称
   #方法__init__()接受创建Car实例所需的信息
    def __init__(self,make,model,year):
        print("__init__()方法被调用")
        #让python调用Car类的方法__init__(),让子类创建的实例包含父类这个方法中定义的所有属性
        super().__init__(make,model,year)#super是一个特殊函数,使我们能够调用父类的方法
        self.battery_size=75
    def describle_battery(self):
        print(f"this car a {self.battery_size}-kwl battery")
my_tesla=ELectricCar('tesla','model s',2019)
print(my_tesla.get_descriptive_name())
my_tesla.describle_battery() 

此时,子类中新增了专有属性describle_battery:

#__init__()方法被调用
2019 Tesla Model S
this car a 75-kwl battery

接下来重点分析新添加的子类专有属性:

  def __init__(self,make,model,year):
        print("__init__()方法被调用")
        #让python调用Car类的方法__init__(),让子类创建的实例包含父类这个方法中定义的所有属性
        super().__init__(make,model,year)#super是一个特殊函数,使我们能够调用父类的方法
        self.battery_size=75
def describle_battery(self):#关于子类ELectricCar特有的描述
        print(f"this car a {self.battery_size}-kwl battery")

self.battery_size=75是子类特有属性,因此定义在子类的__init__()方法中。基于子类ELectricCar创建的所有实例均包含此属性,而父类Car的实例则不包含。

子类的复杂程度无上限。在模拟子类ELectricCar时,可根据需求添加任意数量的属性和方法。

若某属性或方法适用于所有汽车(包括父类Car和子类ELectricCar),应将其置于父类Car中;若仅适用于子类,则置于子类中。这样,父类用户获得通用功能,子类用户获得特有功能。

重写父类的方法

若父类方法不符合子类所模拟实物的行为特征,可进行重写。具体做法是在子类中定义一个与父类方法同名的新方法。此时,Python将忽略父类方法,仅执行子类中定义的方法。

示例如下:

假设父类Car包含fill_gas_tank()方法,这对子类ELectricCar(电动车)而言无意义。若需重写,只需在子类中定义同名方法即可。

class Car:
  ---snip:
    def fill_gas_tank(self):
        self.fill_gas_tank=90
        print(f"电瓶车邮箱尺寸的大小是{self.fill_gas_tank}")
class ELectricCar(Car):
    --snip:
    def fill_gas_tank(self):#与父类中该属性的方法名相同
        print("this car doesn't need a gas tank!")
my_tesla=ELectricCar('tesla','model s',2019)
print(my_tesla.get_descriptive_name())
my_tesla.fill_gas_tank()

重写后,输出结果将反映子类ELectricCar的行为。若不重写,则仍输出父类中不相关的属性行为。

#__init__()方法被调用
2019 Tesla Model S
this car doesn't need a gas tank!

将实例用作属性

在模拟实物时,若类的属性和方法清单及文件过长,可将类的一部分提取为单独的类,将大型类拆分为多个协同工作的小类。

例如,若子类ELectricCar中关于电池的属性与方法过多,可将其提取为名为Battery的类,并将一个Battery实例作为子类ELectricCar的属性:

示例代码如下:

class Car:
    --snip--
class Battery:#这里是重写一个类
    def __init__(self,battery_size=10):#该默认值可设定也可不设定
        self.battery_size=battery_size
    def describle_battery(self):
        print(f"this car has a {self.battery_size}-kwl battery")
class ELectricCar(Car):
    def __init__(self,make,model,year):
        super().__init__(make,model,year)
        self.battery=Battery()#在子类ELectricCar新添加了一个名为battery的属性
        #让python创建一个新的Battery实例,并将该实例赋给属性新创建的属性battery
my_tesla=ELectricCar('tesla','model s',2019)
#和上面描述电池容量是一样的方法
my_tesla.battery.describle_battery()#让python在实例my_tasla中查找属性battery,并对battery进行调用

随后向Battery类添加一个方法,用于描述电动车的续航里程:

class Car:
   --snip--
class Battery:
   --snip--
    def get_range(self):
        if self.battery_size==75:
            range = 260
        elif self.battery_size==100:
            range = 315
        print(f"this car can go about {range} miles on a full charge")
class ELectricCar(Car):
   --snip--
my_tesla=ELectricCar('tesla','model s',2019)
my_tesla.battery.describle_battery()
my_tesla.battery.get_range()#在my_tesla实例中查找battery,self.battery=Battery(),对Battery进行调用
#__init__被调用
this car has a 75-kwl battery
this car can go about 260 miles on a full charge

本文关于Python重写方法和特殊构造方法的介绍到此结束,更多Python相关内容可搜索本站历史文章或继续浏览后续文章,感谢支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。