• 周五. 4月 26th, 2024

python 继承的详细用法

城主

12月 27, 2022 ,

在 Python 中,继承是指一个类(称为子类)可以获取另一个类(称为父类)的属性和方法。这允许您创建新的类,这些类是现有类的扩展。这可以节省代码,并使您能够使用现有类的功能。

继承的基本语法如下:





class SubClassName(ParentClass1[, ParentClass2, ...]):
    # class body

例如,假设您有一个类 Animal,该类有一个 make_sound() 方法,该方法打印动物的叫声:





class Animal:
    def make_sound(self):
        print("Some generic animal sound")

现在,假设您想创建一个新类 Dog,该类是 Animal 的扩展,并具有特定于狗的方法。您可以使用以下代码:





class Dog(Animal):
    def bark(self):
        print("Woof!")

现在,您可以使用 Dog 类创建新的狗对象,并调用其 bark() 方法和 make_sound() 方法。





dog = Dog()
dog.bark()  # Woof!
dog.make_sound()  # Some generic animal sound

您还可以在子类中重写父类的方法。例如,如果您希望在狗叫声中覆盖通用动物叫声,则可以在 Dog 类中定义一个新的 make_sound() 方法:





class Dog(Animal):
    def bark(self):
        print("Woof!")

    def make_sound(self):
        print("Bark bark!")

现在,如果您调用狗对象的 make_sound() 方法,则会打印 “Bark bark!”,而不是 “Some generic animal sound”。

另外,在 Python 中,您还可以使用 super() 函数调用父类的方法。例如,假设您希望在 Dog 类的 make_sound() 方法中调用父类的 make_sound() 方法,并在其中添加一些额外的功能:





class Dog(Animal):
    def bark(self):
        print("Woof!")

    def make_sound(self):
        super().make_sound()  # Call the make_sound method on the parent class
        print("Bark bark!")

现在,如果您调用狗对象的 make_sound() 方法,则会打印 “Some generic animal sound” 和 “Bark bark!”。

阅读  linux下清理redis缓存

在 Python 中,您还可以使用多继承,即一个类可以继承多个父类。例如,假设您有一个类 SwimmingAnimal,该类具有 swim() 方法,以及另一个类 FlyingAnimal,该类具有 fly() 方法。现在,假设您想创建一个新类 Dolphin,该类既可以游泳,又可以飞。您可以使用以下代码:





class Dolphin(SwimmingAnimal, FlyingAnimal):
    def speak(self):
        print("Whistle")

现在,您可以使用 Dolphin 类创建新的海豚对象,并调用其 swim()fly()speak() 方法。





dolphin = Dolphin()
dolphin.swim()  # swim method from SwimmingAnimal
dolphin.fly()  # fly method from FlyingAnimal
dolphin.speak()  # Whistle

在 Python 中,还有一些更复杂的继承概念,例如方法解析顺序(MRO)和抽象基类。

在 Python 中,当一个类有多个父类时,有一种叫做方法解析顺序(Method Resolution Order,MRO)的机制,用于确定在多继承中应该从哪个父类获取方法。

例如,假设您有以下三个类:





class A:
    def method(self):
        print("Method from class A")

class B(A):
    pass

class C(A):
    def method(self):
        print("Method from class C")

现在,假设您有一个类 D,该类同时继承自类 B 和类 C。在这种情况下,MRO 将确定在调用 D 对象的 method() 方法时应调用哪个类的方法。

默认情况下,Python 使用的是深度优先搜索的方式,即先查找类 D 中的方法,然后查找类 B 中的方法,然后是类 A 中的方法,最后是类 C 中的方法。因此,在这种情况下,如果您创建了 D 类的对象并调用其 method() 方法,则会打印 “Method from class C”。

阅读  Python 远程过程调用(RPC)技术详解

但是,您可以使用 Python 的 __mro__ 属性来手动控制 MRO。例如,您可以使用以下代码重写类 D 的 MRO:





class D(B, C):
    __mro__ = (B, C, A, object)  # Specify the MRO manually

现在,如果您创建 D 类的对象并调用其 method() 方法,则会打印 “Method from class A”。这是因为 MRO 已经指定了在调用 D 对象的 method() 方法时,应该首先查找类 B 中的方法,然后是类 C 中的方法,然后是类 A 中的方法,最后是类 object 中的方法。

另一个常见的复杂继承概念是抽象基类。抽象基类是一种特殊类型的类,它不能被直接实例化,而是用作其他类的基类。抽象基类通常包含一些抽象方法,这些方法没有实现,而是由子类来实现。

在 Python 中,您可以使用模块 abc 中的 ABC 类和 abstractmethod 装饰器来创建抽象基类。例如,假设您希望创建一个抽象基类 Shape,该类有一个抽象方法 area(),用于计算形状的面积。您可以使用以下代码:





from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass  # This method has no implementation

现在,如果您尝试直接实例化 Shape 类,则会引发 TypeError,因为它是一个抽象基类。但是,您可以创建一个新的类,该类继继承自 Shape 类,并实现其抽象方法。例如,假设您希望创建一个类 Circle,该类表示圆形。您可以使用以下代码:





class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

现在,您可以使用 Circle 类创建新的圆形对象,并调用其 area() 方法计算面积。





circle = Circle(5)
print(circle.area())  # 78.5

您还可以使用抽象基类来强制子类实现特定的方法。例如,假设您希望所有的形状都必须实现 perimeter() 方法,您可以在 Shape 类中添加一个抽象方法:





from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass  # This method has no implementation

    @abstractmethod
    def perimeter(self):
        pass  # This method also has no implementation

现在,如果您尝试创建一个新的类,该类继承自 Shape 类但没有实现 perimeter() 方法,则会引发 TypeError。因此,您必须在子类中实现所有抽象方法,才能创建该子类的对象。例如,您可以修改 Circle 类以实现 perimeter() 方法:





class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

    def perimeter(self):
        return 2 * 3.14 * self.radius

现在,您可以使用 Circle 类创建新的圆形对象,并调用其 area()perimeter() 方法。





circle = Circle(5)
print(circle.area())  # 78.5
print(circle.perimeter())  # 31.4

希望这些信息能够帮助您了解 Python 中的继承和抽象基类。

阅读  Python手动安装模块,安装库不需要联网