[{"data":1,"prerenderedAt":75},["ShallowReactive",2],{"qa-\u002Fpython\u002Foop\u002Finheritance":3},{"page":4,"siblings":54,"blog":45},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":45,"seo":46,"seoDescription":47,"stem":48,"subtopic":49,"topic":50,"topicSlug":51,"updated":52,"__hash__":53},"qa\u002Fpython\u002Foop\u002Finheritance.md","Inheritance",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","Python","python",{},true,1,"\u002Fpython\u002Foop\u002Finheritance",[23,28,32,36,40],{"id":24,"difficulty":25,"q":26,"a":27},"single-vs-multiple","easy","What is the difference between single and multiple inheritance?","**Single inheritance** means a class derives from exactly one parent; **multiple\ninheritance** means it lists more than one base class. Python supports both —\nmultiple inheritance is what lets you compose behaviour from several sources at\nonce.\n\n```python\nclass Animal:\n    def eat(self): print(\"eating\")\n\nclass Dog(Animal):          # single inheritance\n    def bark(self): print(\"woof\")\n\nclass Swimmer: ...\nclass Flyer: ...\nclass Duck(Animal, Swimmer, Flyer):  # multiple inheritance\n    pass\n```\n\nMultiple inheritance is powerful but can create ambiguity about *which* parent's\nmethod wins — that ambiguity is resolved by the **MRO**. Rule of thumb: prefer\nsingle inheritance plus small **mixins** over deep, wide hierarchies.\n",{"id":29,"difficulty":14,"q":30,"a":31},"what-is-mro","What is the MRO and how is it computed?","The **MRO (Method Resolution Order)** is the linear, ordered list of classes\nPython searches when looking up an attribute or method on an instance. CPython\nbuilds it with the **C3 linearization** algorithm, which guarantees a consistent\norder that respects each class's own order of bases and never places a parent\nbefore its child.\n\n```python\nclass A: ...\nclass B(A): ...\nclass C(A): ...\nclass D(B, C): ...\n\nD.__mro__            # (D, B, C, A, object)\nD.mro()             # same, as a list\n```\n\nC3 produces a single deterministic order (or raises `TypeError` if no consistent\norder exists). Attribute lookup walks this list left to right and stops at the\nfirst match. Rule of thumb: read `Cls.__mro__` whenever multiple inheritance\nsurprises you — it tells you exactly who wins.\n",{"id":33,"difficulty":14,"q":34,"a":35},"how-super-works","How does super() actually work?","`super()` does **not** simply call \"the parent class\" — it calls the **next class\nin the instance's MRO**, starting after the current class. That cooperative\nbehaviour is what makes multiple inheritance work correctly: each class delegates\nto whatever comes next, regardless of the static hierarchy.\n\n```python\nclass A:\n    def greet(self): print(\"A\")\nclass B(A):\n    def greet(self): print(\"B\"); super().greet()\nclass C(A):\n    def greet(self): print(\"C\"); super().greet()\nclass D(B, C):\n    def greet(self): print(\"D\"); super().greet()\n\nD().greet()   # D, B, C, A  — follows D.__mro__, not B's parent\n```\n\nNote `super().greet()` inside `B` calls `C`, not `A`, because the MRO of a `D`\ninstance puts `C` after `B`. Rule of thumb: in a cooperative hierarchy every\noverride should call `super()` so the whole chain runs exactly once.\n",{"id":37,"difficulty":14,"q":38,"a":39},"diamond-problem","What is the diamond problem and how does Python solve it?","The **diamond problem** arises when two classes (`B`, `C`) inherit from a common\nbase (`A`), and a fourth class (`D`) inherits from both. The question is: when\n`D` calls an inherited method, is `A`'s code run **once or twice**? Naive\nlanguages run it twice; Python's **C3 MRO** guarantees `A` appears **exactly\nonce**, so cooperative `super()` calls run it a single time.\n\n```python\nclass A:\n    def __init__(self): print(\"A\"); \nclass B(A):\n    def __init__(self): print(\"B\"); super().__init__()\nclass C(A):\n    def __init__(self): print(\"C\"); super().__init__()\nclass D(B, C):\n    def __init__(self): print(\"D\"); super().__init__()\n\nD()   # D, B, C, A  — A's __init__ runs ONCE\n```\n\nThe MRO `(D, B, C, A, object)` linearizes the diamond into a clean chain. Rule of\nthumb: the diamond is only safe when every class in it uses `super()` consistently\n— mixing `super()` with hard-coded `Base.__init__(self)` calls breaks the\nguarantee.\n",{"id":41,"difficulty":42,"q":43,"a":44},"mixins-and-abc","medium","What are mixins and abstract base classes?","A **mixin** is a small class that provides a focused slice of behaviour meant to be\ncombined into other classes via multiple inheritance — it isn't useful on its own\nand usually has no `__init__`. An **abstract base class (ABC)**, from the `abc`\nmodule, defines an interface with `@abstractmethod`s and **cannot be instantiated**\nuntil every abstract method is overridden.\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass JsonMixin:                 # mixin: adds one capability\n    def to_json(self): import json; return json.dumps(self.__dict__)\n\nclass Shape(ABC):                # abstract base: defines a contract\n    @abstractmethod\n    def area(self): ...\n\nclass Circle(Shape, JsonMixin):\n    def __init__(self, r): self.r = r\n    def area(self): return 3.14159 * self.r ** 2\n\nShape()    # TypeError: can't instantiate abstract class\n```\n\nUse mixins to share reusable behaviour and ABCs to enforce that subclasses\nimplement a required interface (`isinstance` checks also work against ABCs). Rule\nof thumb: mixins say \"you *can* do this\", ABCs say \"you *must* do this\".\n",null,{"description":11},"Python interview questions on single vs multiple inheritance, the MRO and C3 linearization, super(), the diamond problem, mixins, and abstract base classes.","python\u002Foop\u002Finheritance","Inheritance & the MRO","Object-Oriented Programming","oop","2026-06-18","lr7N1CknUWOM5mCsCVypmlwzPFk9qinVKOEqgWAED8Y",[55,56,59,63,67,71],{"subtopic":49,"path":21,"order":20},{"subtopic":57,"path":58,"order":12},"Classes, Instances & __init__","\u002Fpython\u002Foop\u002Fclasses",{"subtopic":60,"path":61,"order":62},"Dunder \u002F Magic Methods","\u002Fpython\u002Foop\u002Fdunder-methods",3,{"subtopic":64,"path":65,"order":66},"Methods & Properties","\u002Fpython\u002Foop\u002Fmethods-properties",4,{"subtopic":68,"path":69,"order":70},"Dataclasses & __slots__","\u002Fpython\u002Foop\u002Fdataclasses-slots",5,{"subtopic":72,"path":73,"order":74},"Abstract Base Classes & Protocols","\u002Fpython\u002Foop\u002Fabc-protocols",6,1781808680118]