В чем ключевые различия в реализации наследования в Python и C#?

«В чем ключевые различия в реализации наследования в Python и C#?» — вопрос из категории ООП, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Главное различие — поддержка множественного наследования реализации.

Аспект C# Python
Наследование реализации Единичное. Класс может наследовать только от одного базового класса. Множественное. Класс может наследовать от нескольких базовых классов.
Наследование контракта Множественное через интерфейсы (interface). Класс может реализовывать много интерфейсов. Не применимо. В Python нет разделения на абстрактные классы и интерфейсы в стиле C#. Роль интерфейсов играют абстрактные базовые классы или просто классы с нереализованными методами.
Разрешение методов (MRO) Линейное, определяется компилятором. Простое, так как цепочка наследования одна. Сложный алгоритм C3 Linearization. Определяет порядок поиска методов при множественном наследовании. Можно посмотреть через ClassName.__mro__.
Вызов родительского метода Ключевое слово base (например, base.MethodName()). Функция super() (например, super().method_name()). При множественном наследовании super() работает согласно MRO.

Пример множественного наследования в Python:

class Engine:
    def start(self):
        print("Engine started")

class Radio:
    def play(self):
        print("Radio playing")

class Car(Engine, Radio):  # Наследуем и от Engine, и от Radio
    pass

my_car = Car()
my_car.start()  # Из класса Engine
my_car.play()   # Из класса Radio

Почему в C# нет множественного наследования? Для избежания проблем "ромбовидного наследования" и неоднозначности вызова методов. Интерфейсы решают задачу множественного наследования поведения без наследования состояния и реализации.