继承和多态通常情况下常见的都是结合使用,但多态并不完全依赖继承
比如鸭子类型,不同类型有>同名方法<的情况,不管它们有没有共同父类,都可能被调用
一、继承和多态的关系
1. **继承是基础**:
通过继承,子类可以复用父类的属性和方法,同时可以 **重写(覆盖)父类的方法**。
**例如**:
- 父类 `动物` 有方法 `叫()`。
- 子类 `狗` 和 `猫` 继承 `动物`,并重写 `叫()` 方法。
2. **多态是表现**:
多态指同一个方法在不同子类中有不同的实现。
**例如**:
- 调用 `狗.叫()` 输出“汪汪”。
- 调用 `猫.叫()` 输出“喵喵”。
二、多态是否需要继承?
- **在静态类型语言(如Java、C++)中**:
多态通常需要继承。因为这些语言要求明确声明类型,必须通过继承关系实现多态。
- **在动态类型语言(如Python)中**:
多态不一定依赖继承。Python 支持 **鸭子类型**(Duck Typing),只要对象有相同的方法名,就能实现多态,无需继承。
# 实例1 基于继承的多态
# 父类
class Animal:
def speak(self):
pass
# 子类
class Dog(Animal):
def speak(self):
print("汪汪!")
class Cat(Animal):
def speak(self):
print("喵喵!")
# 多态调用
def make_animal_speak(animal):
animal.speak()
dog = Dog()
cat = Cat()
make_animal_speak(dog) # 输出:汪汪!
make_animal_speak(cat) # 输出:喵喵!
# 实例2 基于鸭子类型的多态(无需继承)
# 没有继承关系的类
class Dog:
def speak(self):
print("汪汪!")
class Cat:
def speak(self):
print("喵喵!")
class Robot:
def speak(self): # 只要有同名方法即可
print("哔哔!")
# 多态调用(不依赖继承)
def make_speak(obj):
obj.speak()
dog = Dog()
cat = Cat()
robot = Robot()
make_speak(dog) # 输出:汪汪!
make_speak(cat) # 输出:喵喵!
make_speak(robot) # 输出:哔哔!
四、总结
- **继承和多态的关系**:
- 继承是常见的多态实现方式(子类重写父类方法)。
- 多态是继承的一个重要应用场景。
- **多态不强制依赖继承**:
- 在 Python 中,只要对象有相同方法名(鸭子类型),就能实现多态。
- 例如:`len()` 函数可以处理字符串、列表、字典等不同对象,因为它们都实现了 `__len__` 方法。
五、生活中的比喻
1. **继承+多态**:
- 你有一把“通用螺丝刀”(父类),但它不够好用。
- 你改造出“十字螺丝刀”(子类)和“一字螺丝刀”(子类),它们都能拧螺丝(多态),但用法不同。
2. **鸭子类型**:
- 只要能“拧螺丝”的东西(不管是不是螺丝刀),都可以用来拧螺丝。
- 比如用钥匙、硬币甚至手指——只要它们能完成“拧螺丝”的动作。
六、实际应用场景
- **基于继承的多态**:
适合需要严格类型检查和代码复用的场景(如游戏中的不同角色继承自同一个基类)。
- **基于鸭子类型的多态**:
适合灵活的场景(如处理多种数据类型的函数)。
理解这两者的区别后,你可以根据需求选择合适的方式!
相互学习 下期继续
👏👏👏