110 lines
4.5 KiB
Markdown
110 lines
4.5 KiB
Markdown
# Python 继承
|
||
|
||
> 原文:[https://python.land/objects-and-classes/python-inheritance](https://python.land/objects-and-classes/python-inheritance)
|
||
|
||
在编程中,尽可能多地重用代码被认为是一种好的风格。这种做法甚至有一个很好的首字母缩略词,叫做 DRY:不要重复自己。类有助于避免重复代码,因为您可以一次编写一个类,然后基于它创建许多对象。然而,当使用 Python 继承时,它们也以另一种方式帮助你。
|
||
|
||
目录
|
||
|
||
|
||
|
||
* [Python 中的继承](#Inheritance_in_Python "Inheritance in Python")
|
||
* [Python 继承示例](#Python_inheritance_example "Python inheritance example")
|
||
* [覆盖 Python 方法](#Overriding_Python_methods "Overriding Python methods")
|
||
* [覆盖其他方法](#Overriding_other_methods "Overriding other methods")
|
||
* [继续学习](#Keep_learning "Keep learning")
|
||
|
||
|
||
|
||
## Python 中的继承
|
||
|
||
我们已经看到了遗传在起作用,但是你可能还没有意识到。还记得我告诉过你关于 [Python 构造函数](https://python.land/objects-and-classes/python-constructors)以及每个类都有一个构造函数(`__init__`),即使你没有定义一个。这是因为每个类都继承了 Python 中最基本的类,叫做`object`:
|
||
|
||
```py
|
||
>>> dir(object)
|
||
['__class__', '__delattr__', '__dir__',
|
||
'__doc__', '__eq__', '__format__',
|
||
'__ge__', '__getattribute__', '__gt__',
|
||
'__hash__', '__init__', '__init_subclass__',
|
||
'__le__', '__lt__', '__ne__', '__new__',
|
||
'__reduce__', '__reduce_ex__', '__repr__',
|
||
'__setattr__', '__sizeof__', '__str__',
|
||
'__subclasshook__']
|
||
```
|
||
|
||
当我告诉你 Python 中的一切都是对象’时,我指的是一切。这包括类,如你所见,我们也可以在类上使用`dir()`;`object`级。它揭示了`object`有一个`__init__`方法。很酷,不是吗?
|
||
|
||
## Python 继承示例
|
||
|
||
类可以从其他类继承属性和函数,所以不必重复。比方说,我们希望我们的 Car 类从 Vehicle 类继承一些更通用的函数和变量。当我们这样做的时候,让我们也定义一个摩托车类。示意性地看起来是这样的:
|
||
|
||

|
||
|
||
Python 类继承
|
||
|
||
继承映射到许多现实生活中的情况。基于上面的类图,让我们看看继承的实际应用。我们将从一个通用的`Vehicle`类开始:
|
||
|
||
```py
|
||
class Vehicle:
|
||
def __init__(self, started = False, speed = 0):
|
||
self.started = started
|
||
self.speed = speed
|
||
def start(self):
|
||
self.started = True
|
||
print("Started, let's ride!")
|
||
def stop(self):
|
||
self.speed = 0
|
||
def increase_speed(self, delta):
|
||
if self.started:
|
||
self.speed = self.speed + delta
|
||
print("Vrooooom!")
|
||
else:
|
||
print("You need to start me first")
|
||
```
|
||
|
||
现在我们可以使用继承来重新定义我们的汽车类:
|
||
|
||
```py
|
||
class Car(Vehicle):
|
||
trunk_open = False
|
||
def open_trunk(self):
|
||
self.trunk_open = True
|
||
def close_trunk(self):
|
||
self.trunk_open = False
|
||
```
|
||
|
||
我们的汽车继承了 Vehicle 类的所有方法和变量,但是增加了一个额外的变量和两个方法来操作主干。
|
||
|
||
## 覆盖 Python 方法
|
||
|
||
有时你想覆盖继承的`__init__`函数。为了演示,我们可以创建一个摩托车类。大多数摩托车都有一个中间支架。我们将增加在初始化时输出或输入的能力:
|
||
|
||
```py
|
||
class Motorcycle(Vehicle):
|
||
def __init__(self, center_stand_out = False):
|
||
self.center_stand_out = center_stand_out
|
||
super().__init__()
|
||
```
|
||
|
||
当您重写构造函数时,我们从父类继承的构造函数根本不会被调用。如果你还想要那个功能,你就要自己调用它。这是用`super()`完成的:它返回一个对父类的引用,所以我们可以调用父类的构造函数。
|
||
|
||
在这种情况下,我们为中心支架添加了功能,但删除了在构造函数中设置速度和开始状态的选项。如果您愿意,您也可以添加速度和启动状态的选项,并将它们传递给`Vehicle`构造函数。
|
||
|
||
## 覆盖其他方法
|
||
|
||
就像`__init__`一样,我们也可以覆盖其他方法。例如,如果您想要实现一辆不能启动的摩托车,您可以重写 start 方法:
|
||
|
||
```py
|
||
class Motorcycle(Vehicle):
|
||
def __init__(self, center_stand_out = False):
|
||
self.center_stand_out = center_stand_out
|
||
super().__init__()
|
||
def start(self):
|
||
print("Sorry, out of fuel!")
|
||
```
|
||
|
||
## 继续学习
|
||
|
||
这里有一些资源可以更深入地研究这个主题:
|
||
|
||
* 关于继承的官方 Python 指南。 |