python 类的继承

Python中的类继承可以分为以下几种类型:

  1. 单继承:一个子类只继承一个父类。

  2. 多继承:一个子类同时继承多个父类。

  3. 深度优先继承:在多继承中,如果有多个父类具有相同的方法或属性,则会按照从左到右、深度优先的顺序查找并使用第一个符合要求的父类的方法或属性。

  4. 方法重写:一个子类可以重写其父类中的方法,从而改变该方法的实现方式。

  5. 抽象基类:一个抽象基类定义了一组接口,任何继承该类的子类都必须实现这些接口。通过使用抽象基类,可以在编码时规范程序的结构和行为。

下面举例说明单继承和多继承的使用方法:

# 单继承
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print(f"{self.name} is speaking.")

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed

    def speak(self):
        print(f"{self.name} ({self.breed}) is barking.")

dog = Dog("Fido", "Golden Retriever")
dog.speak()  # 输出:Fido (Golden Retriever) is barking.


# 多继承
class Flyer:
    def fly(self):
        print("I can fly.")

class Swimmer:
    def swim(self):
        print("I can swim.")

class Duck(Flyer, Swimmer):
    def quack(self):
        print("Quack!")

duck = Duck()
duck.fly()   # 输出:I can fly.
duck.swim()  # 输出:I can swim.
duck.quack() # 输出:Quack!

在上面的例子中,Animal是一个父类,Dog是Animal的子类,Duck同时继承了Flyer和Swimmer两个父类,因此它既能飞也能游泳。注意,在Dog子类中使用了super()函数来调用父类的构造函数,并且重写了speak()方法以实现不同的行为;在Duck子类中,没有重写任何方法,但是它可以直接使用Flyer和Swimmer两个父类中定义的方法。

对于深度优先继承,我们可以通过修改继承顺序来改变方法或属性的查找顺序。例如:

# 深度优先继承
class A:
    def test(self):
        print("A")

class B(A):
    def test(self):
        print("B")
        super().test()

class C(A):
    def test(self):
        print("C")
        super().test()

class D(B, C):
    def test(self):
        print("D")
        super().test()

d = D()
d.test()  # 输出:D B C A

在上述例子中,类D继承了类B和类C,并重写了test方法。当调用d.test()时,程序会按照B -> C -> A的顺序查找并调用test方法。其中,在调用super().test()时,程序会继续按照类继承顺序向上查找并调用父类的test方法。

对于方法重写,我们可以在子类中重新定义同名的方法,并使用super()函数调用父类中的该方法。例如

# 方法重写
class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Square(Rectangle):
    def __init__(self, side):
        super().__init__(side, side)

square = Square(5)
print(square.area())  # 输出:25

在上述例子中,Square子类重新定义了area方法,并使用super()函数调用了父类Rectangle中的该方法。由于Square继承了Rectangle,因此它也具有计算面积的能力,但是实现方式略有不同。

最后,抽象基类可以使用Python内置的abc模块来实现。例如:

# 抽象基类
import abc

class Shape(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Square(Rectangle):
    def __init__(self, side):
        super().__init__(side, side)

square = Square(5)
print(square.area())  # 输出:25

上述例子中,我们使用了abc模块来定义一个抽象基类Shape,并声明了一个名为area的抽象方法。任何继承自Shape的子类都必须实现area方法,否则会抛出TypeError异常。在Rectangle和Square两个子类中,我们都实现了area方法,因此它们可以正常地计算面积。

 

posted @ 2023-04-30 17:08  乐瓜乐虫  阅读(800)  评论(0编辑  收藏  举报