Object Oriented Python 简明教程
Inheritance and Polymorphism
继承和多态性——这是 Python 中一个非常重要的概念。如果你想学习,你必须更深入地了解它。
Inheritance
面向对象编程的主要优势之一是重用。继承就是实现这一目标的机制之一。继承允许程序员首先创建一个通用类或基类,然后稍后将其扩展为更专门的类。它允许程序员编写更好的代码。
使用继承,你可以使用或继承基类中所有可用的数据字段和方法。稍后,你可以添加自己方法和数据字段,因此继承提供了一种组织代码的方法,而不是从头开始重写它。
在面向对象术语中,当类 X 扩展类 Y 时,Y 被称为超类/父类/基类,X 被称为子类/子类/派生类。这里需要注意的一点是只有非私有的数据字段和方法可供子类访问。私有数据字段和方法仅可在类内访问。
创建派生类的语法为 -
class BaseClass:
Body of base class
class DerivedClass(BaseClass):
Body of derived class
Inheritance Examples
让我们仔细看看继承示例——
让我们创建两个类来参与示例 -
-
动物——模拟动物的类
-
猫——动物的子类
-
狗 - 动物子类
在 Python 中,用于创建对象(实例)并为属性分配值的是类的构造函数。
子类构造函数总是调用父类构造函数以初始化其属性值,然后开始为其属性分配值。
Polymorphism (“MANY SHAPES”)
多态性是 Python 中类定义的一项重要功能,在您跨类或子类拥有同名方法时使用。这允许函数在不同时间使用不同类型的实体。所以,它提供了灵活性并松散耦合,以便随着时间的推移可以扩展和容易维护代码。
这允许函数使用任何这些多态类的对象,而无需了解跨类的区别。
多态性可以通过继承来实现,其中子类使用基类方法或重写它们。
让我们用我们之前关于继承的示例来理解多态性的概念,并在两个子类中添加一个称为 show_affection 的通用方法 −
从示例中我们可以看到,它指的是一种设计,其中不同类型对象可以以相同的方式被对待,或者更具体地说,两个或多个具有同名方法或通用接口的类,因为相同的方法(在本例中为 show_affection)被使用任一类型的对象调用。
Overriding
在 Python 中,当一个子类包含一个覆盖超类方法的方法时,还可以通过调用来调用超类方法
Super(Subclass, self).method 而不是 self.method。
Inheriting the Constructor
如果从我们之前的继承示例中可以看到, init 位于父类中的向上,因为子类 dog 或 cat 没有 init 方法。Python 使用继承属性查找来在 animal 类中查找 init 。当我们创建子类时,它将首先在 dog 类中查找 init 方法,然后在未找到后查看父类 Animal 并找到它们并进行调用。因此,随着我们类设计的变得复杂,我们可能希望首先通过父类构造函数,然后通过子类构造函数来初始化一个实例。
Output
在上例中——所有动物都有一个名称,所有狗都有一个特定的品种。我们使用 super 来调用父类构造函数。因此,dog 有它自己的 init ,但首先发生的是我们调用 super。Super 是内置函数,它旨在将一个类与其超类或其父类相关联。
在这种情况下,我们所说的是获取 dog 的超类并将 dog 实例传递给我们在构造函数中所说的任何方法 init 。因此,换句话说,我们使用 dog 对象调用父类 Animal init 。你可能想知道,为什么我们不直接使用 dog 实例来说 Animal init ,我们也可以这样做,但是如果 animal 类名称在将来某个时间发生更改怎么办。如果我们想要重新排列类层次结构,那么 dog 会从另一个类继承。在这种情况下使用 super 会让事情保持模块化,并且易于更改和维护。
因此,在这个示例中,我们能够将通用 init 功能与更具体的功能相结合。这给了我们机会将通用功能与特定功能分开,这可以消除代码重复,并且以反映系统整体设计的方式将类相互关联。
Multiple Inheritance and the Lookup Tree
顾名思义,多重继承是 Python 中的一个类从多个类继承的情况。
例如,一个孩子从父母(母亲和父亲)双方继承性格特征。
Python Multiple Inheritance Syntax
要让一个类从多个父类继承,我们在定义它时将这些类的名称写在派生类的圆括号中。我们用逗号分隔这些名称。
下面是一个示例:
>>> class Mother:
pass
>>> class Father:
pass
>>> class Child(Mother, Father):
pass
>>> issubclass(Child, Mother) and issubclass(Child, Father)
True
多重继承是指从两个或两个以上的类中继承的能力。当孩子从父母继承,而父母从祖父母类继承时,复杂性就会出现。Python 会爬一个继承树,寻找要从某个对象读取的属性。它将在实例中、类内、父类中和最后从祖父母类中进行检查。现在出现的一个问题是,以什么顺序搜索这些类——广度优先还是深度优先。默认情况下,Python 使用深度优先。
这就是为什么在下面的图表中,Python 首先在类 A 中搜索 dothis() 方法。因此,以下示例中的方法解析顺序为:
Mro- D→B→A→C
查看下面的多重继承图表:
让我们通过一个示例来了解 Python 的“mro”特性的。
Decorators, Static and Class Methods
函数(或方法)通过 def 语句创建。
尽管方法在以下一点上的工作方式与函数完全相同,但方法的第一个参数是实例对象。
我们可以根据其行为方式对方法进行分类,例如:
-
Simple method - 在类外部定义。此函数可以通过提供实例参数来访问类属性:
def outside_func(():
-
Instance method −
def func(self,)
-
Class method - 如果我们需要使用类属性
@classmethod
def cfunc(cls,)
-
Static method - 没有任何关于类的信息
@staticmethod
def sfoo()
到目前为止,我们已经看到了实例方法,现在是时候深入了解其他两种方法了,
syntax
class C(object):
@classmethod
def fun(cls, arg1, arg2, ...):
....
fun: function that needs to be converted into a class method
returns: a class method for function
他们有权访问此 cls 参数,它不能修改对象实例状态。这需要访问 self。
-
它绑定到类,而不是类的对象。
-
类方法仍然可以修改适用于类的所有实例的类状态。