← Все этапы
03 · ПРОЕКТИРОВАНИЕУрок 07 из 1245 мин

Интерфейсы и композиция

Описываем возможности типов и передаём разные реализации одной функции.

Интерфейс задаёт необходимое поведение

Функции удобнее зависеть от действия, которое ей нужно, чем от конкретного типа. Тип реализует интерфейс автоматически, если у него есть требуемые методы.

package main

import "fmt"

type Priced interface {
	DeliveryPrice() int
}

type Route struct{ Distance int }

type Envelope struct{ Route }
func (e Envelope) DeliveryPrice() int { return 100 + e.Distance*2 }

type Box struct {
	Route
	Weight int
}
func (b Box) DeliveryPrice() int { return 200 + b.Distance*2 + b.Weight*10 }

func printPrice(item Priced) {
	fmt.Println(item.DeliveryPrice())
}

func main() {
	printPrice(Envelope{Route: Route{Distance: 5}})
	printPrice(Box{Route: Route{Distance: 5}, Weight: 3})
}

Интерфейс описывает набор методов, нужных потребителю. Реализация не требует ключевого слова: достаточно определить эти методы. Встраивание типа помогает собирать поведение из небольших частей.

Практика

Попробуйте сами

В main.go задайте интерфейс с методом DeliveryPrice() int и функцию, которая принимает этот интерфейс и печатает стоимость. Конверт на расстояние 5 км считайте по формуле 100 + 2*км, коробку на расстояние 5 км весом 3 кг — 200 + 2*км + 10*кг. Передайте оба значения одной функции и запустите go run main.go.

Проверка результата

Как понять, что получилось

Одна и та же функция принимает оба типа; для конверта печатается 110, для коробки — 240. Типы реализуют интерфейс своими методами, без явного объявления реализации.

Интерфейсы и композиция | Go | WebSchool · Go