继承使我们能够定义一个类,该类从父类中获取所有功能,并允许我们添加更多功能。 在本教程中,您将学习在 Python 中使用继承。

Python 继承
继承是面向对象编程中的一项强大功能。
它指的是定义新的类,而对现有类几乎没有修改。 新类称为派生类(或子类),而从其继承的新类称为基类(或父类)。
Python 继承语法
1 2 3 4 |
<span class="pl-k">class</span> <span class="pl-v">BaseClass</span>: <span class="pl-v">Body</span> <span class="pl-s1">of</span> <span class="pl-s1">base</span> <span class="pl-k">class</span> <span class="pl-s1">class</span> <span class="pl-v">DerivedClass</span>(<span class="pl-v">BaseClass</span>): <span class="pl-v">Body</span> <span class="pl-s1">of</span> <span class="pl-s1">derived</span> <span class="pl-s1">class</span> |
派生类从基类继承功能,可以在其中添加新功能。 这导致代码的可重用性。
Python 中的继承示例
为了演示继承的使用,让我们举一个例子。
多边形是具有 3 个或更多边的闭合图形。 说,我们有一个名为Polygon
的类,定义如下。
1 2 3 4 5 6 7 8 9 10 11 |
<span class="pl-k">class</span> <span class="pl-v">Polygon</span>: <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">no_of_sides</span>): <span class="pl-s1">self</span>.<span class="pl-s1">n</span> <span class="pl-c1">=</span> <span class="pl-s1">no_of_sides</span> <span class="pl-s1">self</span>.<span class="pl-s1">sides</span> <span class="pl-c1">=</span> [<span class="pl-c1">0</span> <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">no_of_sides</span>)] <span class="pl-k">def</span> <span class="pl-en">inputSides</span>(<span class="pl-s1">self</span>): <span class="pl-s1">self</span>.<span class="pl-s1">sides</span> <span class="pl-c1">=</span> [<span class="pl-en">float</span>(<span class="pl-en">input</span>(<span class="pl-s">"Enter side "</span><span class="pl-c1">+</span><span class="pl-en">str</span>(<span class="pl-s1">i</span><span class="pl-c1">+</span><span class="pl-c1">1</span>)<span class="pl-c1">+</span><span class="pl-s">" : "</span>)) <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">self</span>.<span class="pl-s1">n</span>)] <span class="pl-k">def</span> <span class="pl-en">dispSides</span>(<span class="pl-s1">self</span>): <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">self</span>.<span class="pl-s1">n</span>): <span class="pl-en">print</span>(<span class="pl-s">"Side"</span>,<span class="pl-s1">i</span><span class="pl-c1">+</span><span class="pl-c1">1</span>,<span class="pl-s">"is"</span>,<span class="pl-s1">self</span>.<span class="pl-s1">sides</span>[<span class="pl-s1">i</span>]) |
此类具有数据属性,以将面数n
和每一面的大小存储为称为side
的列表。
inputSides()
方法采用每边的大小,dispSides()
显示这些边的长度。
三角形是具有 3 个边的多边形。 因此,我们可以创建一个名为Triangle
的类,该类继承自Polygon
。 这使Polygon
类的所有属性可用于Triangle
类。
我们不需要再次定义它们(代码可重用性)。Triangle
可以定义如下。
1 2 3 4 5 6 7 8 9 10 |
<span class="pl-k">class</span> <span class="pl-v">Triangle</span>(<span class="pl-v">Polygon</span>): <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>): <span class="pl-v">Polygon</span>.<span class="pl-en">__init__</span>(<span class="pl-s1">self</span>,<span class="pl-c1">3</span>) <span class="pl-k">def</span> <span class="pl-en">findArea</span>(<span class="pl-s1">self</span>): <span class="pl-s1">a</span>, <span class="pl-s1">b</span>, <span class="pl-s1">c</span> <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-s1">sides</span> <span class="pl-c"># calculate the semi-perimeter</span> <span class="pl-s1">s</span> <span class="pl-c1">=</span> (<span class="pl-s1">a</span> <span class="pl-c1">+</span> <span class="pl-s1">b</span> <span class="pl-c1">+</span> <span class="pl-s1">c</span>) <span class="pl-c1">/</span> <span class="pl-c1">2</span> <span class="pl-s1">area</span> <span class="pl-c1">=</span> (<span class="pl-s1">s</span><span class="pl-c1">*</span>(<span class="pl-s1">s</span><span class="pl-c1">-</span><span class="pl-s1">a</span>)<span class="pl-c1">*</span>(<span class="pl-s1">s</span><span class="pl-c1">-</span><span class="pl-s1">b</span>)<span class="pl-c1">*</span>(<span class="pl-s1">s</span><span class="pl-c1">-</span><span class="pl-s1">c</span>)) <span class="pl-c1">**</span> <span class="pl-c1">0.5</span> <span class="pl-en">print</span>(<span class="pl-s">'The area of the triangle is %0.2f'</span> <span class="pl-c1">%</span><span class="pl-s1">area</span>) |
但是,类Triangle
具有查找和打印三角形区域的新方法findArea()
。 这是一个示例运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">t</span> <span class="pl-c1">=</span> <span class="pl-v">Triangle</span>() <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">t</span>.<span class="pl-en">inputSides</span>() <span class="pl-v">Enter</span> <span class="pl-s1">side</span> <span class="pl-c1">1</span> : <span class="pl-c1">3</span> <span class="pl-v">Enter</span> <span class="pl-s1">side</span> <span class="pl-c1">2</span> : <span class="pl-c1">5</span> <span class="pl-v">Enter</span> <span class="pl-s1">side</span> <span class="pl-c1">3</span> : <span class="pl-c1">4</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">t</span>.<span class="pl-en">dispSides</span>() <span class="pl-v">Side</span> <span class="pl-c1">1</span> <span class="pl-c1">is</span> <span class="pl-c1">3.0</span> <span class="pl-v">Side</span> <span class="pl-c1">2</span> <span class="pl-c1">is</span> <span class="pl-c1">5.0</span> <span class="pl-v">Side</span> <span class="pl-c1">3</span> <span class="pl-c1">is</span> <span class="pl-c1">4.0</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-s1">t</span>.<span class="pl-en">findArea</span>() <span class="pl-v">The</span> <span class="pl-s1">area</span> <span class="pl-s1">of</span> <span class="pl-s1">the</span> <span class="pl-s1">triangle</span> <span class="pl-c1">is</span> <span class="pl-c1">6.00</span> |
我们可以看到,即使我们没有为类Triangle
分别定义inputSides()
或dispSides()
之类的方法,我们仍然可以使用它们。
如果在类本身中找不到属性,则搜索继续到基类。 如果基类本身是从其他类派生的,则将递归重复此操作。
Python 中的方法覆盖
在上面的示例中,请注意,在Triangle
和Polygon
这两个类别中都定义了__init__()
方法。 发生这种情况时,派生类中的方法将覆盖基类中的方法。 也就是说,Triangle
中的__init__()
优先于Polygon
中的__init__
。
通常,当覆盖基本方法时,我们倾向于扩展定义而不是简单地替换它。 通过从派生类中的基类中调用基类中的方法(从Triangle
中的__init__()
中调用Polygon.__init__()
)来完成相同的操作。
更好的选择是使用内置函数super()
。 因此,super().__init__(3)
等同于Polygon.__init__(self,3)
,因此是首选。 要了解有关 Python 中super()
函数的更多信息,请访问 Python super()
函数。
两个内置函数isinstance()
和issubclass()
用于检查继承。
如果对象是该类或从其派生的其他类的实例,则函数isinstance()
返回True
。 Python 中的每个类都继承自基类object
。
1 2 3 4 5 6 7 8 9 10 11 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">isinstance</span>(<span class="pl-s1">t</span>,<span class="pl-v">Triangle</span>) <span class="pl-c1">True</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">isinstance</span>(<span class="pl-s1">t</span>,<span class="pl-v">Polygon</span>) <span class="pl-c1">True</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">isinstance</span>(<span class="pl-s1">t</span>,<span class="pl-s1">int</span>) <span class="pl-c1">False</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">isinstance</span>(<span class="pl-s1">t</span>,<span class="pl-s1">object</span>) <span class="pl-c1">True</span> |
同样,issubclass()
用于检查类继承。
1 2 3 4 5 6 7 8 |
<span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">issubclass</span>(<span class="pl-v">Polygon</span>,<span class="pl-v">Triangle</span>) <span class="pl-c1">False</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">issubclass</span>(<span class="pl-v">Triangle</span>,<span class="pl-v">Polygon</span>) <span class="pl-c1">True</span> <span class="pl-c1">>></span><span class="pl-c1">></span> <span class="pl-en">issubclass</span>(<span class="pl-s1">bool</span>,<span class="pl-s1">int</span>) <span class="pl-c1">True</span> |