Введение в интерфейсы
Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 25 из 107.
interface в Go определяет набор сигнатур method, не реализуя их. Он описывает, что может делать тип, а не то, как он это делает. Любой тип, который реализует все method в interface, автоматически соответствует этому interface.
Вот как определить interface:
type Speaker interface {
Speak() string
}Этот интерфейс Speaker требует, чтобы любой реализующий его тип имел метод Speak(), возвращающий строку. Теперь любую структуру с этим методом можно использовать везде, где ожидается Speaker.
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " says woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " says meow!"
}И Dog, и Cat удовлетворяют интерфейсу Speaker, потому что у каждого из них есть method Speak() с правильной сигнатурой. Теперь можно писать function, которые accepts любой Speaker:
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy говорит гав!
MakeSound(cat) // Whiskers говорит мяу!
}Интерфейсы позволяют писать гибкий, повторно используемый код, который работает с любым типом, соответствующим требованиям интерфейса, независимо от базовой реализации.
Задание
ЛегкоДавайте создадим систему описания транспортных средств, которая демонстрирует, как интерфейсы позволяют разным типам совместно использовать общее поведение. Вы создадите интерфейс, которому смогут соответствовать несколько типов транспортных средств, а затем будете использовать его для единообразного описания любого транспортного средства.
Вы организуете код в двух файлах:
vehicles.go: Define интерфейсDescriberс единственным методомDescribe() string. Затем создайте две структуры, соответствующие этому интерфейсу:Carс полямиBrandиModel(оба имеют тип string)Bicycleс полямиType(string) иGears(int)
Describe(), возвращающий описательную строку о транспортном средстве.main.go: Создайте function с именемPrintDescription, которая принимает любойDescriberи выводит результат вызова его методаDescribe(). Считайте информацию о транспортных средствах из input, создайте Car и Bicycle и используйте свою function, чтобы вывести описание каждого из них.
Будут предоставлены следующие входные данные:
- Строка 1: марка Car
- Строка 2: модель Car
- Строка 3: тип Bicycle
- Строка 4: количество gears (целое число)
Ваши методы Describe() должны возвращать строки в следующих форматах:
- Car:
[Brand] [Model] - Bicycle:
[Type] bike with [Gears] gears
Например, если заданы Toyota, Camry, Mountain и 21, результатом должен быть:
Toyota Camry
Mountain bike with 21 gearsГлавная идея заключается в том, что ваша function PrintDescription работает с любым типом, у которого есть метод Describe(). Ей не нужно знать, работает ли она с Car, Bicycle или любым другим типом транспортного средства, который вы добавите позже.
Попробуйте сами
package main
import (
"fmt"
)
// TODO: Создайте функцию PrintDescription, которая принимает любой Describer
// и выводит результат вызова её метода Describe()
func main() {
// Читаем ввод
var carBrand string
var carModel string
var bicycleType string
var gears int
fmt.Scanln(&carBrand)
fmt.Scanln(&carModel)
fmt.Scanln(&bicycleType)
fmt.Scanln(&gears)
// TODO: Создайте Car с brand и model из ввода
// TODO: Создайте Bicycle с type и gears из ввода
// TODO: Используйте PrintDescription для вывода описания car
// TODO: Используйте PrintDescription для вывода описания bicycle
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП в Go
Внешние файлыРабочее пространство и модули GoПакеты и импортыЭкспортируемые и неэкспортируемые именаВведение в ООП в GoСтруктуры как классыОпределение методов структурПолучатели-указатели и получатели-значенияИнициализация структурФункции-конструкторыИтоги — Простой калькулятор4Интерфейсы
Введение в интерфейсыНеявная реализацияИнтерфейс как контрактПустой интерфейс (any)Утверждение типаПереключатель типовКомпозиция интерфейсовИнтерфейсы Stringer и ErrorПовторение: Калькулятор фигур7Инкапсуляция
Экспортируемые и неэкспортируемые поляИнкапсуляция на уровне пакетовГеттеры и сеттерыСокрытие информации в GoИтоги — Записи о студентах10Обобщения (Generics) (Go 1.18+)
Введение в GenericsПараметры типовОграничения типовОбобщенные структурыОбходной путь для обобщенных методовИтоги — Обобщенная коллекция13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн Abstract FactoryПаттерн ObserverПаттерн Strategy2Глубокое погружение в типы и структуры
Базовые и составные типыОпределение пользовательских типовТеги структурАнонимные структурыВложенные структурыНулевые значения и значения по умолчаниюПовторение — Контактная книга5Композиция вместо наследования
Почему в Go нет наследованияОсновы встраивания структурПродвижение методовВстраивание нескольких структурВстраивание против агрегацииЗатенение встроенных методовИтоги — Иерархия сотрудников8Обработка ошибок и ООП
Интерфейс errorПользовательские типы ошибокОбертывание ошибок (fmt.Errorf)Sentinel-ошибкиerrors.Is() и errors.As()Panic, Defer и RecoverИтоги — Парсер файлов11Стандартная библиотека и ООП
io.Reader и io.Writersort.InterfaceИнтерфейс fmt.Stringerencoding/json со структурамиИнтерфейс http.HandlerПовторение: модели REST API14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикMiddleware как Декоратор3Указатели и память
Основы указателей в GoУказатели на структурыПередача по значению и по ссылкеФункция new()Сборка мусора в GoПовторение: Конструктор связного списка6Полиморфизм в Go
Полиморфизм через интерфейсыУтиная типизация в GoПравила реализации интерфейсовПолиморфные коллекцииВнедрение зависимостейИтоги — Обработчик платежей9Конкурентность и ООП
Основы горутинКаналы и взаимодействиеБуферизованные и небуферизованные каналыОператор selectsync.Mutex и sync.RWMutexsync.WaitGroupПроектирование потокобезопасных структурПовторение — Worker PoolПотренируйтесь самостоятельно: Онлайн-компилятор Go