(十)python之多态

本文详细介绍了Python面向对象编程的三大特性:封装、继承和多态,以及多继承的工作原理。通过实例展示了如何创建类、使用属性和方法,以及如何实现多态。此外,还探讨了Python中的鸭子类型,强调关注对象的行为而非其类型。面向对象编程的概念有助于理解代码的组织和扩展性,并遵循“开放封闭”原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、面向对象三大特征

面向对象编程的三大特征:封装,集成,多态

  • 封装:客官的事物封装成类(将数据和方法放在一个类中就构成了封装)
  • 继承:在python中一个类可以集成于另一个类也可以继承多个类,被继承的类叫父类(或者叫基类,base class),继承的类叫子类
  • 多态(polymorphism):指的是一类事物有多种形态,一个抽象类有多个子类(因而多态的概念依赖于继承),不同的子类对象调用相同的方法,产生不同的执行结果,多态可以增加代码的灵活度

二、多继承(拓展)

(1)Demo类同时继承A类和B类,然后Demo类实例化一个对象d,这个对象d可以调用A类和B类里面的属性和方法。

class A:
    a_attr1 = 100

    def func_a(self):
        print('------func_a--------')


class B:
    b_attr1 = 999

    def func_b(self):
        print('------func_b--------')


class Demo(A, B):
    pass


d = Demo()
# 调用父类A的属性和方法
print(d.a_attr1)
d.func_a()

# 调用父类B的属性和方法
print(d.b_attr1)
d.func_b()


# 打印结果
100
------func_a--------
999
------func_b--------

(2) 如果继承了2个类,调用两个父类中同名的方法和属性会怎么取值呢?

答:就近原则,他先找括号里面左边这个类,左边这个类找到了就不会再去找右边这个类,左边的类如果找不到就去右边这个类找。

注意:如果demo这个类自己有这个方法,就不会再去父类里面找,如果demo这个类没有,才会去父类里面去找。

class A:
    a_attr1 = 100
    attr = 10

    def func_a(self):
        print('----funca——————')

    def work(self):
        print('----funca——work————')


class B:
    b_attr1 = 999
    attr = 99999

    def func_b(self):
        print('----funcb——————')

    def work(self):
        print('----funcb——work————')


class Demo(A, B):
    pass


d = Demo()

# 调用两个父类中同名的方法和属性
print(d.attr)



# 打印结果
10

(3)只读属性(property) 

方法名上面加了@property之后,不再是方法名,而是属性名称

class B:
    b_attr1 = 999
    attr = 99999

    def func_b(self):
        print('----funcb——————')

    def work(self):
        print('----funcb——work————')


class Demo(A, B):
    def work(self):
        print('demo---work')

    @property  # 定义只读属性
    def battr(self):
        return B.attr


d = Demo()

# 只读属性
print(d.battr)


# 打印结果
99999

(4)多继承的应用思想

"""
定义一个api测试的用例类
    1、用例数据处理
    2、接口请求
    3、响应数据提取
    3、断言




"""


class HandleData:
    pass


class RequestApi:
    pass


class BaseTest(HandleData, RequestApi):
    pass

三、多态

实现多态的步骤:

  • 1、定义一个父类(Base),实现某个方法(比如:run)
  • 2、定义多个子类,在子类中重写父类的方法(run),每个子类run方法实现不同的功能
  • 3、假设我们定义了一个函数,需要一个Base类型的对象的参数,那么调用函数的时候,传入Base类不同的子类对象,那么这个函数就会执行不同的功能,这就是多态的体现。

还是不懂多态是啥意思吗?没关系,我们上一段代码就明白了。

一个父类,他具有多个子类,不同的子类在调用相同的方法,执行的时候产生不同的形态,这个叫多态。

class Animal(object):
    """动物类"""

    def func(self):
        print('动物发出了声音')


class Cat(Animal):
    """猫类"""

    def func(self):
        print('喵 喵 喵')


class Dog(Animal):
    """狗类"""

    def func(self):
        print('汪 汪 汪 ')


class Hero:
    def func(self):
        print('这个是英雄类的方法,不是动物类的对象')


def work01(musen: Animal):
    musen.func()


work01(Hero())

多态的意义:

  • 对于一个变量,我们只需要知道他是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法(调用方只管调用,不管细节)
  • 当需要新增功能,只需要新增一个Animal的子类实现run()方法,就可以在原来的基础上进行功能扩展,这就是著名的“开放封闭”原则:​​​​​​​

“开放封闭”原则:

  • 对扩展开放:允许新增Animal子类
  • 对修改封闭:不需要修改依赖Animal类型的run()等函数

注意点:Python中函数的参数是没有类型限制的,所以多态在python中的体现并不是很严谨。多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

class Animal(object):
    """动物类"""

    def func(self):
        print('动物发出了声音')


class Cat(Animal):
    """猫类"""

    def func(self):
        print('喵 喵 喵')


class Dog(Animal):
    """狗类"""

    def func(self):
        print('汪 汪 汪 ')


class Hero:
    def func(self):
        print('这个是英雄类的方法,不是动物类的对象')


def work01(musen: Animal):
    musen.func()


work01(Hero())

四、鸭子类型

  • 鸭子类型概念:他并不要求严格的继承体系,关注的不是对象的类型本身,而是它是否具有要调用的方法(行为)
  • 鸭子类型在python中的案例:
    ​​​​​​​
    内置函数iter:参数可以是实现迭代协议(__iter__方法)的任何类型的对象。
    ​​​​​​​
"""
"""
鸭子类型概念:它并不要求严格的继承体系,关注的不是对象的类型,而是它是否具有要调用的方法(行为)。
鸭子类型在python中的案例:
    内置函数iter:参数可以是实现迭代协议(`__iter__`方法)的任何类型的对象

"""

li = [11, 22, 33, 44]
s = '1212124'


class MyTest:
    def __iter__(self):
        return (i for i in range(10))

    def __len__(self):
        return 10


li1 = iter(li)  # 内置函数iter将可迭代对象转换为迭代器,,本质上是调用对象的__iter__
s1 = iter(s)  # 内置函数iter将可迭代对象转换为迭代器,,本质上是调用对象的__iter__
m = MyTest()
m1 = iter(m)

# 内置函数len获取数据的长度,本质上是调用对象的__len__
print(len(m))

### Python中的继承 在Python中,类可以通过继承机制创建子类。这允许新定义的类从现有类获取属性和方法。这种特性有助于代码重用并简化程序结构[^1]。 ```python class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError("Subclasses must implement this method") class Dog(Animal): # 继承自Animal类 def speak(self): return f"{self.name} says Woof!" ``` 上述例子展示了如何通过`Dog`类继承`Animal`基类来实现特定行为的方法覆盖。当实例化`Dog`对象时,可以调用其父级提供的通用接口`speak()`,但返回的是针对该具体类型的响应[^2]。 ### 多态多态是指不同类的对象能够以统一的方式被处理的能力。这意味着即使两个对象属于不同的类别,只要它们实现了相同名称的方法就可以互换使用。 ```python def make_animal_speak(animal: Animal): print(animal.speak()) dog = Dog('Rex') make_animal_speak(dog) # 输出: Rex says Woof! ``` 在这个场景下,函数`make_animal_speak`接受任何实现了`speak`方法的对象作为参数,并能正常工作而无需关心传入的具体类型是什么。这就是所谓的基于鸭子 typing 的动态语言特性之一,在这里体现了面向对象编程中的多态概念。 ### 向上转型 (Upcasting) 向上转型指的是将派生类转换成基底类的过程,这是自动完成的操作。例如: ```python animal = Dog('Buddy') # 创建一个Dog实例赋给变量animal print(isinstance(animal, Animal)) # True ``` 此片段说明了一个事实——尽管`animal`实际上是一个`Dog`实例,但它也可以被视为更广泛的`Animal`类型的一部分。 ### 下降转型 (Downcasting) 下降转型涉及相反方向的变化;即尝试把基础类视作某个具体的衍生类来看待。需要注意的是,这类操作通常不推荐因为可能导致运行期错误除非绝对必要并且确认安全的情况下才应考虑这样做。 ```python # 不建议的做法 if isinstance(animal, Dog): dog_specific_behavior = cast(Dog, animal).bark_loudly() else: raise TypeError("Not a Dog instance") ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值