python面试题:Python中的继承
如果你之前写过 Java 或 C++,那对“继承”这个概念肯定不陌生。Python 作为一门支持面向对象编程的语言,自然也支持继承——而且它的继承机制非常灵活,甚至可以多继承,也支持动态修改类的行为,这点比很多静态语言都“开放”得多。
在 Python 中,继承的基本写法非常简单:
classAnimal:
defspeak(self):
print("动物在叫")
classDog(Animal):
defspeak(self):
print("汪汪")
d = Dog()
d.speak() # 输出:汪汪
这段代码里,Dog 继承了 Animal,然后重写了 speak 方法。这个重写行为在 Python 中完全没有关键词(像 Java 的 @Override),你直接写同名方法就可以了。
如果你还想调用父类的 speak 方法怎么办?用 super():
classDog(Animal):
defspeak(self):
super().speak()
print("然后是:汪汪")
这个 super() 是 Python 提供的标准方式,推荐写法也是 super().method(),它在多继承场景下比直接 Animal.method(self) 更可靠,因为它遵循 MRO(方法解析顺序)。
说到多继承,Python 是支持的,而且挺好用。你可以这样:
classA:
defwhoami(self):
print("A")
classB:
defwhoami(self):
print("B")
classC(A, B):
pass
c = C()
c.whoami() # 输出 A(根据 MRO)
Python 会按照 C(A, B) 的顺序来查找方法。这套机制是 C3 线性化算法,简单来说就是:优先找自己 -> 左边的父类 -> 右边的父类 -> 再往上祖宗找,不回头,保证每个类只被访问一次。
但多继承也别乱用,尤其当多个父类都有同名属性或方法时,很容易踩坑。你可能以为调用的是 A 结果是 B,那 bug 找起来就痛苦了。所以除非确实需要组合多个行为,推荐还是单继承 + 组合。
还有一个细节是构造函数的继承。在 Python 里如果子类不写 __init__,默认会调用父类的构造函数。如果子类写了 __init__,你想保留父类初始化逻辑,就得显式用 super():
classAnimal:
def__init__(self, name):
self.name = name
classDog(Animal):
def__init__(self, name, breed):
super().__init__(name)
self.breed = breed
这种写法在实际项目里特别常见,尤其是你定义了一个通用基类,比如 BaseModel、BaseService,子类再去继承和扩展。
另外,有些时候你并不打算让基类被实例化,而是让它只做“接口模板”,这时候你可以写一个抽象基类(ABC):
from abc import ABC, abstractmethod
classAnimal(ABC):
@abstractmethod
defspeak(self):
pass
这样的话,只要子类没实现 speak(),你就没法实例化它,强制别人必须实现指定方法。这在做通用接口或策略模式时非常有用。
所以总结来看,Python 的继承机制比你想象的自由多了,也更动态。你甚至可以运行时给对象加方法、改类名、改父类(当然不建议这么干),但正常开发里还是以“清晰+稳定”为主,别过度魔法化。
面试最优回答:
Python 支持类的继承,包括单继承和多继承。子类可以重写父类方法,也可以通过 super() 调用父类逻辑。Python 中继承的查找顺序遵循 MRO(方法解析顺序),多继承下也能保持一致性。
在构造函数中,若子类定义了自己的 __init__,则需显式调用 super().__init__() 来确保父类初始化逻辑被执行。在项目中经常通过继承构建通用服务类或模型基类,也使用抽象基类(ABC)定义接口规范。
最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek
也可以看我写的这篇文章《DeepSeek满血复活,直接起飞!》来进行本地搭建。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。