Menu
Coddy logo textTech

Введение в интерфейсы

Часть раздела Объектно-ориентированное программирование путешествия по 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 говорит мяу!
}

Интерфейсы позволяют писать гибкий, повторно используемый код, который работает с любым типом, соответствующим требованиям интерфейса, независимо от базовой реализации.

challenge icon

Задание

Легко

Давайте создадим систему описания транспортных средств, которая демонстрирует, как интерфейсы позволяют разным типам совместно использовать общее поведение. Вы создадите интерфейс, которому смогут соответствовать несколько типов транспортных средств, а затем будете использовать его для единообразного описания любого транспортного средства.

Вы организуете код в двух файлах:

  • 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
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Go