Python面向对象编程之继承与多态详解

yizhihongxing

Python面向对象编程之继承与多态详解

1. 继承

继承是面向对象编程中的一个重要概念,它允许子类继承父类的属性和方法。在 Python 中,我们可以通过以下方式来实现继承:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"Hello, my name is {self.name} and I'm {self.age} years old.")

class Student(Person):
    def __init__(self, name, age, school):
        super().__init__(name, age)
        self.school = school

    def introduce(self):
        super().introduce()
        print(f"I'm a student of {self.school}.")

在上面的代码中,我们定义了一个父类 Person 和一个子类 Student。子类通过在类定义中将父类作为参数来继承父类,即:

class Student(Person):
    ...

在子类中,我们可以使用 super() 函数来调用父类的方法。在上面的代码中,我们通过 super().__init__(name, age) 的方式调用了父类的 __init__() 方法。另外,在子类中我们也可以重写父类的方法,这样就可以对父类方法进行扩展或修改。在上面的代码中,我们重写了父类的 introduce() 方法,同时调用了父类的 introduce() 方法。

2. 多态

多态是面向对象编程中的另一个重要概念,它允许不同类的对象使用相同的方法名称,但是具体执行的方法实现不同。在 Python 中,我们可以通过以下方式来实现多态:

class Animal:
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        print("Bark")

class Cat(Animal):
    def make_sound(self):
        print("Meow")

在上面的代码中,我们定义了一个父类 Animal 和两个子类 DogCat。它们都继承了 Animal 父类,并且都重写了父类的 make_sound() 方法。在使用过程中,我们可以根据具体的对象类型来调用相应的方法:

animals = [Dog(), Cat()]

for animal in animals:
    animal.make_sound()  # 根据具体的对象类型调用相应的方法

在上面的代码中,我们将两个不同的动物对象 Dog()Cat() 放在了列表 animals 中,并且通过 for in 循环遍历列表中的每个元素。在循环过程中,我们根据具体的对象类型来调用相应的 make_sound() 方法。在输出结果中,我们可以看到,针对不同的对象类型,执行的方法实现是不同的,这就是多态的体现。

3. 示例说明

示例一

假设我们现在有一个父类 Vehicle 和两个子类 CarBus,其中 CarBus 都继承了 Vehicle 父类,并且都重写了父类的 run() 方法。在 Car 子类中,我们还新增了一个 fly() 方法。下面是示例代码:

class Vehicle:
    def run(self):
        pass

class Car(Vehicle):
    def run(self):
        print("Car is running")

    def fly(self):
        print("Car is flying")

class Bus(Vehicle):
    def run(self):
        print("Bus is running")

如果我们现在需要编写一个函数,这个函数接受一个 Vehicle 类型的参数,并且调用这个参数的 run() 方法,我们该如何实现呢?

def test_vehicle(v: Vehicle):
    v.run()

上面这段代码就是一个示例。我们定义了一个函数 test_vehicle,这个函数接受一个类型为 Vehicle 的参数,并且调用参数的 run() 方法。

下面是测试代码:

car = Car()
bus = Bus()
vehicles = [car, bus]

for vehicle in vehicles:
    test_vehicle(vehicle)

在上面的代码中,我们创建了一个 Car 类的对象 car,一个 Bus 类的对象 bus,并且将它们放在一个列表 vehicles 中。然后我们通过 for in 循环遍历每个元素,并且将其作为参数传递给 test_vehicle() 函数进行测试。

输出结果如下:

Car is running
Bus is running

我们可以看到,在 test_vehicle 函数中,我们只调用了 Vehicle 类的 run() 方法,而具体执行的方法却是 Car 类和 Bus 类中的重写方法,这就是多态的体现。

示例二

假设我们现在有一个父类 Animal 和两个子类 DogCat,它们都继承了 Animal 父类,并且都重写了父类的 make_sound() 方法。下面是示例代码:

class Animal:
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        print("Bark")

class Cat(Animal):
    def make_sound(self):
        print("Meow")

如果我们想让代码更加灵活,支持更多的动物种类。我们可以新增一个子类 Sheep,重写 make_sound() 方法。下面是示例代码:

class Sheep(Animal):
    def make_sound(self):
        print("Baa")

然后我们可以在测试代码中,向 animals 列表中新增一个 Sheep 实例对象,并且调用 test_animal() 函数进行测试。

dog = Dog()
cat = Cat()
sheep = Sheep()
animals = [dog, cat, sheep]

for animal in animals:
    test_animal(animal)

输出结果如下:

Bark
Meow
Baa

我们可以看到,新增一个子类 Sheep 并没有影响原有的代码,同时它也可以正常的使用多态。这就是面向对象编程中的继承与多态。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python面向对象编程之继承与多态详解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • C++超详细讲解泛型

    C++超详细讲解泛型攻略 什么是泛型 泛型是一种编程方式,可以编写能够处理多种数据类型的代码模板。也就是说,泛型可以让我们写出适用于多种类型数据的代码,而无需为每个具体的数据类型编写特定的代码。 在C++中,泛型主要由函数模板和类模板来实现。 函数模板 函数模板可以实现适用于多种类型数据的函数代码。函数模板的定义格式如下: template<typen…

    other 2023年6月27日
    00
  • 基于Redis分布式BitMap的应用分析

    基于Redis分布式BitMap的应用分析攻略 1. 什么是Redis分布式BitMap Redis是一种高性能的键值存储系统,而BitMap是一种数据结构,用于存储和操作位数据。Redis分布式BitMap是将BitMap数据结构与Redis的分布式特性相结合,实现了在分布式环境下对BitMap进行存储和操作的功能。 2. Redis分布式BitMap的应…

    other 2023年8月2日
    00
  • java数组复制===clone()

    Java数组复制===clone() 在Java中,数组是一种非常重要和常见的数据结构。在某些情况下,我们需要复制一个数组,这时候可以使用clone()方法。本文将详细介绍Java数组复制方法clone()。 什么是clone()方法? clone()方法是Object类中的方法,它用于创建并返回当前对象的一份拷贝,也就是一个独立的新对象。数组也是一种对象,…

    其他 2023年3月28日
    00
  • javascrip关于继承的小例子

    我们来详细讲解一下“JavaScript关于继承的小例子”的完整攻略。 基本概念 在 JavaScript 中,继承是一种重要的功能,它允许我们通过创建一个新对象来扩展已有的对象。通过继承,我们可以避免重复编写相同的代码,提高代码复用性,同时也可以提高程序的灵活性。 JavaScript 中的继承实现方式有很多种,其中最常见的两种方式是原型链继承和类继承。 …

    other 2023年6月27日
    00
  • PHP实现无限级分类(不使用递归)

    下面我会详细讲解如何使用 PHP 实现无限级分类,并且不使用递归的方式。 什么是无限级分类 无限级分类是指分类与分类之间存在父子关系,每个分类下都可以包含多个子分类,而每个子分类又可以包含多个子分类,以此类推,可以无限延伸下去的分类体系。它在很多网站的分类功能中都有使用,比如商品分类、文章分类等。 不使用递归的无限极分类实现 从数据库中获取所有分类的数据。 …

    other 2023年6月26日
    00
  • SVN服务器搭建图文教程

    下面是一份详细的SVN服务器搭建教程攻略。其中我以Ubuntu16.04为例进行示范。如果您使用的是其他的Linux发行版,可能会有略微不同的步骤。 准备工作 首先,我们需要在服务器上安装Subversion(SVN)软件包。 sudo apt-get update sudo apt-get install subversion 创建SVN仓库 在服务器上创…

    other 2023年6月27日
    00
  • 关于JVM翻越内存管理的墙

    关于JVM翻越内存管理的墙攻略 JVM(Java虚拟机)是Java程序的运行环境,它负责管理内存、执行字节码等任务。在某些情况下,我们可能需要绕过JVM的内存管理机制,直接操作内存。下面是一份详细的攻略,介绍如何翻越JVM的内存管理墙。 步骤一:使用Unsafe类 Java的sun.misc.Unsafe类提供了直接操作内存的方法,可以绕过JVM的内存管理。…

    other 2023年8月1日
    00
  • java获取文件扩展名的方法小结【正则与字符串截取】

    Java获取文件扩展名的方法小结【正则与字符串截取】 在Java中,获取文件扩展名的方法有多种。本文将介绍两种常用的方法:正则表达式和字符串截取。 方法一:正则表达式 使用正则表达式可以方便地从文件名中提取出扩展名。下面是一个示例代码: import java.util.regex.Matcher; import java.util.regex.Patter…

    other 2023年8月6日
    00
合作推广
合作推广
分享本页
返回顶部