文章目录
- 一、什么是多态?
- 二、多态的实现
- 1.通过继承实现多态
- 2.抽象类实现多态
- 2.1 抽象类的实现
- 2.2 抽象类的注意事项
- 2.3 总结
- 三、注意事项
- 四、总结
- 随笔练习抽象类
在面向对象编程中,多态是一种强大的概念,它允许不同类型的对象对相同的消息做出不同的响应。Python作为一门支持面向对象编程的语言,也支持多态。
一、什么是多态?
多态(Polymorphism)是指在面向对象编程中,不同类型的对象可以使用相同的接口,而具体的实现方式则各不相同。
换句话说,当我们调用一个方法时,不同的对象可以以不同的方式来响应这个方法调用。
这种极大地提高了代码的可复用性和可扩展性。
多态即是面向对象编程的三大特性之一,另外两个是封装和继承。
二、多态的实现
Python通过动态类型语言的特点来实现多态,即在运行时根据实际对象的类型进行方法调用。具体来说,Python中的多态实现依赖于以下两个特性:
- 动态绑定(Dynamic Binding):在运行时根据对象的类型确定方法的具体实现;
- 鸭子类型(Duck Typing):只要一个对象“走起路来像鸭子、叫起来像鸭子”,那么它就可以被视为鸭子。
1.通过继承实现多态
下面通过一个例子来说明Python中的多态实现:
class Animal:def __init__(self, name):self.name = namedef speak(self):raise NotImplementedError('Subclass must implement abstract method')class Dog(Animal):def speak(self):return 'Woof!'class Cat(Animal):def speak(self):return 'Meow!'def animal_speak(animal):print(animal.speak())dog = Dog('Tommy')cat = Cat('Kitty')animal_speak(dog)# 输出:Woof!animal_speak(cat)# 输出:Meow!
在上面的例子中,我们定义了一个Animal类和两个子类Dog和Cat,它们分别实现了speak()方法。
animal_speak()函数接受任何一个Animal对象,并调用其speak()方法。
由于Python是动态类型语言,因此在运行时可以根据实际传入的对象类型确定调用哪个speak()方法。
2.抽象类实现多态
抽象类是一种只能被继承而不能被实例化的类。它定义了一个通用的接口,子类必须实现这个接口中定义的方法或属性。抽象类的存在可以让我们在设计和编写代码时更加灵活和规范。抽象类的主要作用有两个:
- 提供一种规范:抽象类定义了子类应该具备的方法或属性,确保了子类的一致性。
- 强制子类实现:抽象类要求子类必须实现抽象类中定义的方法或属性,否则会在运行时抛出异常。
2.1 抽象类的实现
Python中的抽象类通过abc模块来实现。该模块提供了ABC(Abstract Base Class)类和abstractmethod装饰器,用于定义抽象类和抽象方法。
语法:
from abc import ABC, abstractmethodclass 类名(ABC):@abstractmethoddef 函数名(self):pass或者逻辑
下面是一个简单的示例:
from abc import ABC, abstractmethodclass AbstractClassExample(ABC):@abstractmethoddef method1(self):pass@abstractmethoddef method2(self):passclass ConcreteClassExample(AbstractClassExample):def method1(self):print("Method 1 implementation")def method2(self):print("Method 2 implementation")# 抽象类无法实例化# example = AbstractClassExample()# 子类可以实例化并调用方法example = ConcreteClassExample()example.method1()# 输出:"Method 1 implementation"example.method2()# 输出:"Method 2 implementation"
在上面的示例中,AbstractClassExample是一个抽象类,它继承自ABC类。method1()和method2()被abstractmethod装饰器修饰,表示它们是抽象方法,子类必须实现这两个方法。
ConcreteClassExample是一个具体类,它继承自AbstractClassExample。
由于ConcreteClassExample重写了method1()和method2(),因此它可以实例化并调用这两个方法。
2.2 抽象类的注意事项
在使用抽象类时,需要注意以下几点:
- 抽象类不能被实例化:抽象类只能用作其他类的基类,不能直接创建实例。
- 子类必须实现所有抽象方法:子类必须实现抽象类中定义的所有抽象方法,否则会在运行时抛出异常。如果子类没有实现所有抽象方法,它也会被视为抽象类。
- 抽象方法可以有实现:抽象方法可以在抽象类中有默认实现,但子类仍然可以选择重写这些方法。
- 抽象类可以包含非抽象方法:抽象类中除了抽象方法外,还可以包含普通的方法和属性。
2.3 总结
抽象类是一种不能被实例化的类,它定义了其他类的通用接口和行为。Python通过abc模块来实现抽象类,使用ABC类作为基类和abstractmethod装饰器来定义抽象类和抽象方法。使用抽象类可以提供代码的规范性和灵活性,强制子类实现抽象方法,从而提高代码的可靠性和可维护性。然而,在使用抽象类时,需要注意抽象类不能被实例化、子类必须实现所有抽象方法等事项。
三、注意事项
虽然多态可以提高代码的可复用性和可扩展性,但也需要注意一些问题。
- 抽象基类应该定义规范的接口,确保所有实现该接口的子类都能够正确地响应相应的方法调用。
- 尽管Python是一门动态类型语言,但仍然需要注意调用的方法是否存在,以避免在运行时抛出AttributeError异常。
- 当有多个子类实现了同一个方法时,需要确保每个子类的实现方式是相互独立的,以避免意外地影响其他子类的正确性。
四、总结
多态是面向对象编程中非常重要的一个概念,它可以提高代码的可复用性和可扩展性。
Python作为一门支持面向对象编程的语言,通过动态类型语言的特点来实现多态,即在运行时根据实际对象的类型进行方法调用。同时,我们也需要注意抽象基类的规范定义、方法调用的存在性以及子类实现方式相互独立等问题。
随笔练习抽象类
from abc import ABC,abstractmethod"""1.需要使用abc模块实现抽象类,即定义抽象类的时候需要class 抽象类名称(ABC):2.实现抽象类,要将抽象方法都实现3.抽象类不能被实例化,会报错TypeError: Can't instantiate abstract class Animal with abstract methods cood, speak4.抽象类中可以有构造函数,可以有普通函数5.抽象方法可以有实现"""class Animal(ABC):def __init__(self,type):self.type = typedef speak(self):print("要吃冻干")@abstractmethoddef speak(self):pass# 抽象方法可以有实现@abstractmethoddef cood(self):print("要吃冻干")class Cat(Animal):color = Nonedef speak(self):print("要吃冻干")def cood(self):print("要吃冻干")cat = Cat("1")cat.speak()