当前位置:   article > 正文

Python学习之-继承和多态_python继承和多态的理解

python继承和多态的理解

前言:

什么是继承?什么是多态?
面向对象的三大特性:
封装:根据 职责 将属性和方法封装到一个抽象类
继承: 实现代码的重用,相同的代码不需要重复的编写
多态: 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
继承
继承是一种机制,它使得一个类(称为子类或派生类)能够继承另一个类(称为父类或基类)的属性和行为(方法)。子类除了可以继承父类的功能外,还可以添加新的功能或重写某些功能。
单继承: 当一个类仅继承自一个父类时。
多继承: 当一个类继承自多个父类时。
继承使得创建和维护应用程序变得更加容易,因为它促进了复用代码,并且允许创建类的层次结构。
多态
多态是一个广义的概念,描述了不同类的对象对同一个方法调用可以产生不同的行为。多态使得我们可以在不考虑对象具体类型的情况下,对对象进行操作。
在 Python 中,多态是隐式实现的,因为 Python 是一种动态类型语言,没必要在代码中专门声明类型。只要对象具有所调用的方法,Python 就会执行它。 这意味着我们可以针对不同的对象,通过同一接口调用在各自类中定义的方法。

1. 单继承

单继承指的是一个子类仅继承自一个父类。这意味着子类可以继承父类的公有属性和方法,可以添加新的属性和方法,或者覆盖继承来的方法。

1.1 单继承示例:

#!/usr/bin/env python
# coding=utf-8
# Author: Summer
# Time: 2024.04.1

class Animal:  # 父类
    def __init__(self, name):
        self.name = name

    def speak(self):
        raise NotImplementedError("子类必须实现这个方法")


class Dog(Animal):  # 子类
    def speak(self):
        return f"{self.name} says Woof!"


class Cat(Animal):  # 子类
    def speak(self):
        return f"{self.name} says Meow!"


dog = Dog("Buddy")
cat = Cat("Kitty")

print(dog.speak())  # 输出: Buddy says Woof!
print(cat.speak())  # 输出: Kitty says Meow!

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这个例子中,Dog 和 Cat 类继承自 Animal 类。每个子类都有一个 speak 方法,它们各自返回不同的内容。这体现了单继承的基本用法。

2 多继承

多继承指的是一个子类可以同时继承多个父类。Python 支持多继承,它允许子类继承多个父类的属性和方法。多继承需要仔细设计以避免复杂的继承结构和潜在的名称冲突。

2.1 多继承示例:

#!/usr/bin/env python
# coding=utf-8
# Author: Summer
# Time: 2024.04.1


class Father:
    def __init__(self):
        print("This is the father.")

    def characteristic(self):
        print("Father's characteristic")

    def father_skill(self):
        print("我会说中文,这是爸爸的技能。。")


class Mother:
    def __init__(self):
        print("This is the mother.")

    def characteristic(self):
        print("Mother's characteristic")

    def mother_skill(self):
        print("我会说英文,这是妈妈的技能。。")


class Child(Father, Mother):  # 继承自 Father 和 Mother
    def __init__(self):
        super().__init__()  # 调用第一个父类的构造方法

    def parent_characteristic(self):
        super().characteristic()  # 自动调用第一个匹配的父类方法


child = Child()  # This is the father.
child.parent_characteristic()  # Father's characteristic

child.mother_skill()  # 我会说英文,这是妈妈的技能。。

child.father_skill()  # 我会说中文,这是爸爸的技能。。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

在这个例子中,Child 类继承自 Father 和 Mother 类。来自父类的 init 方法由 super().init() 调用,但由于 Python 解析父类的顺序(MRO-Method Resolution Order),只有 Father 的 init 被调用。相同地,characteristic 方法的调用也遵循 MRO,所以调用的是 Father 类中的实现。这个顺序可以通过 Child.mro() 查看。同样child类拥有他父类的两个方法,可以在实例化child类的时候直接调用父类的方法。
在 Python 的多继承中,MRO 的顺序特别重要,因为它决定了方法调用时从哪个父类开始查找。Python 使用一种称为 C3 线性化的算法来确定继承顺序,确保每个父类在其所有子类之前,并且每个类只被访问一次。

2.2 单继承和多继承的优缺点:

单继承和多继承各有优缺点,单继承结构更简单,继承关系更清晰。而多继承可以创建更灵活的设计,但可能导致结构复杂且难以跟踪,特别是在存在多个层次和相同方法名时。设计良好的接口和清晰的继承策略对于避免多继承带来的复杂性至关重要。

3. 父类方法的重写

在对象导向编程中,子类有时需要修改它从父类继承的行为。这可以通过重写(或覆盖)父类中的方法来实现。当子类有一个与父类同名的方法时,这个方法会覆盖父类的方法。在子类实例中调用该方法时,执行的将是子类中定义的版本。

#!/usr/bin/env python
# coding=utf-8
# Author: Summer
# Time: 2024.04.1

# 父类
class Vehicle:
    def __init__(self, name):
        self.name = name

    def honk(self):
        return "Honk! This is a general vehicle."


# 子类
class Car(Vehicle):
    def __init__(self, name, brand):
        super().__init__(name)  # 调用父类的构造方法,初始化 name 属性
        self.brand = brand  # 新属性

    # 重写父类的 honk 方法
    def honk(self):
        return f"Beep! This is a {self.brand} car named {self.name}."


# 实例化父类
vehicle = Vehicle("General Vehicle")
print(vehicle.honk())  # 输出: Honk! This is a general vehicle.

# 实例化子类
car = Car("Model S", "Tesla")
print(car.honk())  # 输出: Beep! This is a Tesla car named Model S.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这个例子中,Vehicle 是一个基类,定义了车辆的一般性质和行为。它有一个 honk 方法,用于表示车辆可以鸣笛。
Car 是 Vehicle 的一个子类,定义了更具体的汽车。它重写了 honk 方法,提供了更详细的鸣笛声说明。通过重写 honk 方法,Car 类专门化了它从 Vehicle 继承来的行为。

4. 多态

多态是一个广义的概念,描述了不同类的对象对同一个方法调用可以产生不同的行为。多态使得我们可以在不考虑对象具体类型的情况下,对对象进行操作。
在 Python 中,多态是隐式实现的,因为 Python 是一种动态类型语言,没必要在代码中专门声明类型。只要对象具有所调用的方法,Python 就会执行它。 这意味着我们可以针对不同的对象,通过同一接口调用在各自类中定义的方法。

#!/usr/bin/env python
# coding=utf-8
# Author: Summer
# Time: 2024.04.1

# 父类
class Animal:
    def speak(self):
        pass


# 子类 Dog
class Dog(Animal):
    def speak(self):
        return "Woof!"


# 子类 Cat
class Cat(Animal):
    def speak(self):
        return "Meow!"


# 函数 accept_animal 不需要知道具体类型,只需要知道传入的对象有 speak() 方法
def accept_animal(animal):
    print(animal.speak())


# 实例化子类
dog = Dog()
cat = Cat()

# 执行多态行为
accept_animal(dog)  # 输出 Woof!
accept_animal(cat)  # 输出 Meow!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在上面的例子中,Dog 和 Cat 类都继承自 Animal 类,并覆盖了 speak 方法。函数 accept_animal 可以接受任何类型的 Animal(包括它的子类),并调用 speak 方法。当 accept_animal 函数使用 Dog 和 Cat 对象调用时,它表现出多态性,因为它调用的确切方法取决于对象的实际类型。

总结:

继承和多态是 OOP(面向对象) 的架构支柱,分别提供了代码重用和接口一致性的能力。这些概念在设计灵活和可维护的代码时尤其重要。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/428695
推荐阅读
相关标签
  

闽ICP备14008679号