一. 前言
Python中的抽象类、多态和鸭子类型都是实现代码灵活性的机制,但它们之间还是有一些区别的。
二. 三者的区别
- 抽象类: 要求子类必须实现某些方法,从而规范了子类的实现方式。
- 多态: 同一个方法可以针对不同类型的对象进行不同的实现,提高了代码的灵活性。
- 鸭子类型: 不关心对象的类型,只关心对象是否具有某些特定的方法或属性。
三. 概念及示例代码
1. 多态
1.1 多态的三种表现形式:
- 继承抽象类
- 耦合度极高,程序的可扩展性极低
- 继承父类
- 耦合度高,程序的可扩展性低
- 鸭子类型
- 耦合度低,程序的可扩展性高
1.2 多态的目的:
为了在不知道对象具体类型的情况下,统一对象调用方法的规范(名字)
父类: 定制一套统一的规范。(比如: 方法名统一)
子类: 遵循父类的统一的规范。(比如: 子类遵循父类方法名的统一)
1.3 多态的好处:
- 增加了程序的灵活性
以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(people1)
- 增加了程序的可扩展性
通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(people1)
去调用
1.4 多态示例代码
class People(Animal): #属于动物的另外一种形态:人
def speak(self):
print('say hi')
def func(people): #对于使用者来说,自己的代码根本无需改动
people.speak()
people1=People() #实例出一个人
func(people1) #甚至连调用方式也无需改变,就能调用人的talk功能
'''
这样我们新增了一个形态People,由People类产生的实例people1,使用者可以在完全不需要修改自己代码的情况下,
使用和猫、狗、猪一样的方式调用people1的speak方法,即func(people1)
'''
示例代码二
class Shape:
def area(self):
pass
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def print_area(shape):
print(shape.area())
s = Square(5)
c = Circle(3)
print_area(s) # 25
print_area(c) # 28.26
在上述代码中,Shape
类是一个基类,定义了一个方法area()
。Square
和Circle
类继承了Shape
类,并分别实现了自己的area()
方法。print_area()
函数接受一个Shape
类型的参数,不同类型的Shape
对象会产生不同的行为,实现了多态。
2. 抽象类
2.1 什么是抽象类?
在python内置的abc模块中,有一个抽象类,让子类必须遵循父类的编写规范。
2.2 如何实现抽象类
- 父类需要继承abc模块中的metaclass=abc.ABCMeta
- 在父类的方法中,需要装饰上 abc.abstractmethod
注意:
-
在python中不推荐使用抽象类。
-
子类必须按照父类的方法编写规范,缺一不可。(只要父类中有几个抽象方法,子类就必须要定义几个,可以多,但不能少)
2.3 抽象类示例代码
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
# 不能实例化Shape
# s = Shape()
sq = Square(5)
c = Circle(3)
print(sq.area()) # 25
print(c.area()) # 28.26
在上述代码中,Shape
类是一个抽象类,定义了一个抽象方法area()
。Square
和Circle
类继承了Shape
类,并分别实现了自己的area()方法。由于Shape
是抽象类,不能直接实例化,只能通过子类进行实例化。
3. 鸭子类型
3.1 什么是鸭子类型
- python崇尚鸭子类型,不同的对象,只要长得像鸭子,动作行为像鸭子,那它就是鸭子。
- 鸭子类型是多态的一种表现形式。
3.2 为什么要有鸭子类型
不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范。所有的类,在定义时都按照统一的规范进行编写。
3.3 鸭子类型示例代码
class Duck:
def quack(self):
print("Quack")
class Person:
def quack(self):
print("I'm quacking like a duck")
def duck_test(obj):
obj.quack()
d = Duck()
p = Person()
duck_test(d) # Quack
duck_test(p) # I'm quacking like a duck
在上述代码中,Duck
和Person
类都有一个quack()
方法,duck_test()
函数接受一个对象参数,只要该对象有quack()
方法即可,不关心其具体类型,实现了鸭子类型。
四. 总结:
- 抽象类是一种特殊的类,不能被实例化。它的作用是规范子类的行为。
- 多态是一种基于继承的特性,同一个方法可以针对不同类型的对象进行不同的实现。
- 鸭子类型是一种动态类型机制,关注对象的行为而不关注其类型,只要一个对象实现了特定的接口,就可以被当做该接口的实现对象。
以上就是关于Python -【多态,抽象类,鸭子类型】的区别及使用介绍,希望对你有所帮助!