# Python 继承与多态
> 原文: [https://thepythonguru.com/python-inheritance-and-polymorphism/](https://thepythonguru.com/python-inheritance-and-polymorphism/)
* * *
于 2020 年 1 月 7 日更新
* * *
继承允许程序员首先创建一个通用类,然后再将其扩展为更专业的类。 它还允许程序员编写更好的代码。
使用继承,您可以继承所有访问数据字段和方法,还可以添加自己的方法和字段,因此继承提供了一种组织代码的方法,而不是从头开始重写代码。
在面向对象的术语中,当`X`类扩展了`Y`类时,则`Y`被称为*超类*或*基类*,而`X`被称为*子类或派生类*。 还有一点要注意,子类只能访问非私有的数据字段和方法,私有数据字段和方法只能在该类内部访问。
创建子类的语法是:
```py
class SubClass(SuperClass):
# data fields
# instance methods
```
让我们以一个例子来说明这一点。
```py
class Vehicle:
def __init__(self, name, color):
self.__name = name # __name is private to Vehicle class
self.__color = color
def getColor(self): # getColor() function is accessible to class Car
return self.__color
def setColor(self, color): # setColor is accessible outside the class
self.__color = color
def getName(self): # getName() is accessible outside the class
return self.__name
class Car(Vehicle):
def __init__(self, name, color, model):
# call parent constructor to set name and color
super().__init__(name, color)
self.__model = model
def getDescription(self):
return self.getName() + self.__model + " in " + self.getColor() + " color"
# in method getDescrition we are able to call getName(), getColor() because they are
# accessible to child class through inheritance
c = Car("Ford Mustang", "red", "GT350")
print(c.getDescription())
print(c.getName()) # car has no method getName() but it is accessible through class Vehicle
```
**预期输出**:
```py
Ford MustangGT350 in red color
Ford Mustang
```
在这里,我们创建了基类`Vehicle`及其子类`Car`。 注意,我们没有在`Car`类中定义`getName()`,但是我们仍然可以访问它,因为类`Car`从`Vehicle`类继承。 在上面的代码中,`super()`方法用于调用基类的方法。 这是`super()`的工作方式
假设您需要在子类的基类中调用名为`get_information()`的方法,则可以使用以下代码进行调用。
```py
super().get_information()
```
同样,您可以使用以下代码从子类构造器中调用基类构造器。
```py
super().__init__()
```
## 多重继承
* * *
与 Java 和 C# 等语言不同,python 允许多重继承,即您可以同时从多个类继承,
```py
class Subclass(SuperClass1, SuperClass2, ...):
# initializer
# methods
```
让我们举个例子:
```py
class MySuperClass1():
def method_super1(self):
print("method_super1 method called")
class MySuperClass2():
def method_super2(self):
print("method_super2 method called")
class ChildClass(MySuperClass1, MySuperClass2):
def child_method(self):
print("child method")
c = ChildClass()
c.method_super1()
c.method_super2()
```
**预期输出**:
```py
method_super1 method called
method_super2 method called
```
如您所见,因为`ChildClass`继承了`MySuperClass1`,`MySuperClass2`,所以`ChildClass`的对象现在可以访问`method_super1()`和`method_super2()`。
## 覆盖方法
* * *
要覆盖基类中的方法,子类需要定义一个具有相同签名的方法。 (即与基类中的方法相同的方法名称和相同数量的参数)。
```py
class A():
def __init__(self):
self.__x = 1
def m1(self):
print("m1 from A")
class B(A):
def __init__(self):
self.__y = 1
def m1(self):
print("m1 from B")
c = B()
c.m1()
```
**预期输出**:
```py
m1 from B
```
在这里,我们从基类中重写`m1()`方法。 尝试在`B`类中注释`m1()`方法,现在将运行`Base`类中的`m1()`方法,即`A`类。
**预期输出**:
```py
m1 from A
```
## `isinstance()`函数
* * *
`isinstance()`函数用于确定对象是否为该类的实例。
**语法**: `isinstance(object, class_type)`
```py
>>> isinstance(1, int)
True
>>> isinstance(1.2, int)
False
>>> isinstance([1,2,3,4], list)
True
```
下一章[异常处理](/python-exception-handling/)。
* * *
* * *