Ответ
Интерфейсы в Go фундаментально отличаются от интерфейсов в классических ООП-языках. Их философия построена вокруг композиции и поведения, а не иерархии наследования. Ключевые отличия:
-
Неявная реализация (Implicit Implementation) В Go тип удовлетворяет интерфейсу автоматически, если он реализует все его методы. Не нужно использовать ключевые слова вроде
implements
илиinherits
. Это способствует слабой связности (loose coupling) кода.// Интерфейс, описывающий поведение type Writer interface { Write([]byte) (int, error) } // Тип, который реализует это поведение type ConsoleWriter struct{} // Реализация метода делает ConsoleWriter совместимым с Writer func (cw ConsoleWriter) Write(data []byte) (int, error) { // ... реализация записи в консоль return len(data), nil } // Теперь переменной типа Writer можно присвоить значение типа ConsoleWriter // var w Writer = ConsoleWriter{}
-
Утиная типизация (Duck Typing) Это следствие неявной реализации. Принцип звучит так: «Если что-то ходит как утка и крякает как утка, то это утка». В Go, если тип имеет необходимые методы, он может быть использован там, где ожидается соответствующий интерфейс, без какой-либо формальной связи между ними.
-
Интерфейсы содержат только методы В отличие от некоторых языков, интерфейсы в Go не могут содержать поля или свойства. Они определяют исключительно поведение (набор методов).
-
Пустой интерфейс
interface{}
(илиany
) Пустой интерфейсinterface{}
(в Go 1.18+ его псевдоним —any
) не имеет методов. Поскольку любой тип имеет ноль или более методов, любой тип удовлетворяет пустому интерфейсу. Это позволяет создавать функции, принимающие значения абсолютно любого типа, что является основой для обобщенного программирования (до появления дженериков). -
Внутреннее устройство Интерфейсное значение (interface value) — это пара, состоящая из указателя на информацию о конкретном типе (type) и указателя на само значение этого типа (value). Это позволяет выполнять вызовы методов динамически в рантайме.