Полиморфизм с интерфейсами в Golang
Интерфейсы в Golang работают в совершенно особенной манере в сравнении с интерфейсами на других языках серверного программирования. Прежде чем углубляться в тему, начнём с базовых понятий. Интерфейсы в Golang предоставляют список сигнатур функций, которые реализовываются любой «структурой» для работы с конкретными интерфейсами. Давайте разберёмся, что под этим подразумевается.
Особенности интерфейсов:
Интерфейсы определяют контракт функции.
Интерфейсы в Golang представлены типами.
Давайте определим простой интерфейс для сотрудника employee
…
Здесь к интерфейсу Employee
мы добавляем две функции — GetDetails
и GetEmployeeSalary
. Любая структура или тип, которым нужно работать с интерфейсом Employee
, должна содержать эти функции, указанные как контракт интерфейса. Так используются преимущества интерфейса.
Теперь определим новый тип Manager
, реализующий эти функции контракта, чтобы и он мог воспользоваться преимуществами интерфейса Employee
.
Здесь у нас определён тип
, который выполняет контракт, указанный интерфейсом Employee
. Давайте посмотрим, какие преимущества предлагает интерфейс при работе с этими вновь определёнными типами.
Интерфейсы в Golang представлены «типами»
Интерфейсы можно использовать как «типы» в Golang, то есть мы можем создать переменные типа Interface
и любая структура, выполняющая контракт на функцию, может быть присвоена этой переменной Interface
.
Так же как Manager
, объявляя любые типы, содержащие все функциональные требования к контракту интерфейса Employee
, мы сможем создать их объекты и присвоить их переменной Interface
. Вот пример:
Стоит сделать несколько замечаний:
Мы создали объект для структуры типа
Manager
.Структура
Manager
содержит все функции, требующиеся для интерфейсаEmployee
.Создана переменная типа
Employee
.Объект
Manager
присвоен переменнойemployeeInterface
.employeeInterface
теперь может использоваться для вызова функций, принадлежащих интерфейсу типаEmployee
.
Здесь мы создали переменную интерфейсного типа, и любая структура, содержащая все функции, указанные в контракте интерфейса, может быть ей присвоена. Следовательно, мы могли присвоить объект типа Manager
интерфейсу типа Employee
.
Интерфейсы в Golang отличаются своеобразием…
Эта особенность заметно выделяет его по реализации интерфейса на фоне других серверных языков. Главные выводы, которые можно сделать на основе этого кода:
В Golang интерфейсы можно использовать как типы.
Объект, имеющий все интерфейсные функции, можно присвоить переменной интерфейса.
Давайте напишем весь сценарий
Полиморфизм с интерфейсами Golang
То, что мы можем создавать переменную типа Interface
и присваивать ей объект Struct
, даёт дополнительное преимущество. Теперь появилась возможность присваивать объекты разных типов интерфейсу, который выполняет функциональный контракт и вызывает из него функцию. То есть мы имеем дело с полиморфизмом.
Давайте сделаем реализацию другого типа Struct
со всеми функциями, требующимися интерфейсу Employee
. Создадим новый тип Lead
, реализующий эти функции. Он содержит все функции, указанные в контракте интерфейса. Значит, можно присвоить объект переменным интерфейса.
В этом коде мы присваиваем переменной интерфейса либо объект типа Lead
, либо объект типа Manager
. Получаем, таким образом, общий интерфейс для вызова одной и той же функции, принадлежащей разным типам. Вот он наш полиморфизм.
Использование интерфейса в качестве параметра функции
Интерфейс может быть добавлен в функцию в качестве параметра. В этом случае параметр входного значения может принимать любой объект, удовлетворяющий контракту интерфейса, и затем использоваться для вызова из него функций. Это форма полиморфизма времени выполнения, где одну и ту же переменную можно использовать для вызова функции из разных типов объекта. Вот пример:
Оба типа объектов реализуют функцию, принадлежащую интерфейсу, поэтому они могут передаваться любой функции, принимающей интерфейс в качестве входного параметра.
Использование интерфейсов как типов в структурах
Определяя новый тип данных, мы можем использовать интерфейс в качестве типа параметра (если тип параметра определяется как интерфейс). Любую структуру, реализующую контракт функции, можно присвоить этому параметру.
Покажем это на простых примерах:
Здесь структура Person
содержит параметр User
интерфейсного типа Employee
. Попробуем присвоить параметру User
различные структуры Lead
и Manager
.
Здесь интерфейс используется в качестве типа параметра Struct
.
Ссылки
Last updated
Was this helpful?