В языке, подобном C ++, который допускает множественное наследование и не имеет интерфейсов, абстрактные классы, в которых все методы являются абстрактными, могут служить интерфейсами. Я не так много работал с C ++, но, полагаю, множественное наследование может вызвать проблемы, когда в базовых классах есть методы с одинаковыми именами.
В таких языках, как PHP и C #, интерфейсы предоставляют средства для достижения аналогичного полиморфизма, хотя мне не нравится называть это «наследованием», поскольку существует концептуальная разница между наследованием абстрактного класса и реализацией интерфейса. Интерфейсы устраняют проблему конфликта, потому что они сами не обеспечивают реализацию.
Интерфейс служит контрактом с внешним миром, в то время как абстрактный класс может обеспечивать реализацию, хотя, если он используется для «подделки» интерфейса, он, скорее всего, не будет.
Основное концептуальное отличие состоит в том, что когда класс наследует другой класс (абстрактный или нет), возникает отношение «есть», поэтому «а» Car
есть «а» Vehicle
и « Dog
есть» Animal
. С интерфейсом важно то, что делает объект. Таким образом, Car
и Dog
может, Move()
и потребитель знает это, потому что они реализуют Movable
, но Автомобиль определенно не Dog
, или Animal
. И реализация перемещения будет отличаться (колеса против ног), но код потребления не заботится и не должен волноваться. Интерфейсы все о потреблении кода, а не о реализации.
Главное, если у вас есть интерфейсы на выбранном вами языке, используйте их для вещей, для которых они существуют. Если нет (как в C ++), вы можете подделать их, используя чисто абстрактные классы.