Концептуально интерфейс используется для формального и полуформального определения набора методов, которые будет предоставлять объект. Формально означает набор имен методов и сигнатур, полуформально означает удобочитаемую документацию, связанную с этими методами. Интерфейсы - это только описания API (в конце концов, API означает Application Programmer Interface ), они не могут содержать какую-либо реализацию, и невозможно использовать или запускать интерфейс. Они только делают явный договор о том, как вы должны взаимодействовать с объектом.
Классы предоставляют реализацию, они могут объявить, что они реализуют ноль, один или несколько интерфейсов. Если класс предназначен для наследования, соглашение заключается в добавлении префикса имени класса к «Base».
Существует различие между базовым классом и абстрактным базовым классом (ABC). ABC смешивают интерфейс и реализацию вместе. Аннотация за пределами компьютерного программирования означает «резюме», то есть «Аннотация == Интерфейс». Затем абстрактный базовый класс может описывать как интерфейс, так и пустую, частичную или полную реализацию, которая предназначена для наследования.
Мнения о том, когда использовать интерфейсы и абстрактные базовые классы, а не только классы, будут сильно различаться в зависимости от того, что вы разрабатываете, и от того, на каком языке вы разрабатываете. Интерфейсы часто ассоциируются только со статически типизированными языками, такими как Java или C #, но динамически типизированные языки также могут иметь интерфейсы и абстрактные базовые классы. В Python, например, проводится четкое различие между классом, который объявляет, что он реализует интерфейс, и объектом, который является экземпляром класса и, как говорят, обеспечивает этот интерфейс. На динамическом языке возможно, что два объекта, которые являются экземплярами одного и того же класса, могут объявить, что они предоставляют полностью различные интерфейсы. В Python это возможно только для атрибутов объекта, в то время как методы являются общим состоянием для всех объектов класса. Однако в Ruby объекты могут иметь методы для каждого экземпляра, поэтому вполне возможно, что интерфейс между двумя объектами одного и того же класса может варьироваться настолько, насколько этого желает программист (однако в Ruby нет никакого явного способа объявления интерфейсов).
В динамических языках интерфейс к объекту часто неявно предполагается, либо путем интроспекции объекта и запроса его, какие методы он предоставляет (Look Before You Leap), либо, предпочтительно, просто пытаясь использовать требуемый интерфейс для объекта и перехватывая исключения если объект не предоставляет этот интерфейс (проще просить прощения, чем разрешения). Это может привести к «ложным срабатываниям», когда два интерфейса имеют одинаковое имя метода, но семантически различаются, однако компромисс заключается в том, что ваш код более гибок, так как вам не нужно заранее указывать заранее, чтобы предвидеть все возможные варианты использования вашего кода.