Menu
Coddy logo textTech

Promowanie metod

Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 36 z 107.

Tak jak osadzanie struktur przenosi pola do zewnętrznej struktury, Go przenosi również metody z osadzonych typów. Oznacza to, że możesz wywoływać metody zdefiniowane w osadzonej strukturze bezpośrednio na zewnętrznej strukturze.

type Engine struct {
    Horsepower int
}

func (e Engine) Start() string {
    return "Engine started"
}

type Car struct {
    Model string
    Engine  // osadzony
}

Ponieważ Car osadza Engine, metoda Start() jest automatycznie promowana:

func main() {
    c := Car{
        Model:  "Sedan",
        Engine: Engine{Horsepower: 200},
    }
    
    fmt.Println(c.Start())         // Silnik został uruchomiony
    fmt.Println(c.Engine.Start())  // również działa
}

Ta promocja ma ważną konsekwencję dla interfejsów. Jeśli typ osadzony spełnia wymagania interfejsu, typ zewnętrzny również automatycznie je spełnia:

type Starter interface {
    Start() string
}

func Ignite(s Starter) {
    fmt.Println(s.Start())
}

func main() {
    c := Car{Model: "Sedan", Engine: Engine{Horsepower: 200}}
    Ignite(c)  // Car spełnia interfejs Starter dzięki Engine
}

Typ Car nigdy jawnie nie implementuje Starter, a mimo to spełnia wymagania interfejsu, ponieważ osadzony w nim typ Engine ma wymaganą metodę. W ten sposób Go umożliwia ponowne wykorzystanie zachowania bez tradycyjnego dziedziczenia.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system odtwarzacza muzyki, który pokazuje, jak metody osadzonych typów są promowane do typu zewnętrznego oraz jak dzięki temu kompozycja umożliwia spełnienie wymagań interfejsu.

Rozmieścisz kod w dwóch plikach:

  • audio.go: Utwórz podstawowe elementy odtwarzacza muzyki:
    • Strukturę AudioPlayer z polem Brand (string) oraz metodą Play() string, która zwraca [Brand] playing audio
    • Interfejs Playable, który wymaga metody Play() string
    • Strukturę Smartphone z polem Model, która osadza AudioPlayer
    • Strukturę Tablet z polem Model, która osadza AudioPlayer
  • main.go: Utwórz funkcję o nazwie StartPlayback, która przyjmuje dowolny typ spełniający interfejs Playable i zwraca wynik wywołania Play(). Odczytaj informacje o urządzeniach z wejścia, utwórz zarówno smartfon, jak i tablet, a następnie pokaż, że oba spełniają interfejs Playable dzięki osadzonemu AudioPlayer, mimo że żaden z tych typów nie implementuje jawnie metody Play().

Podane zostaną następujące dane wejściowe:

  • Wiersz 1: Nazwa modelu smartfona
  • Wiersz 2: Marka odtwarzacza audio w smartfonie
  • Wiersz 3: Nazwa modelu tabletu
  • Wiersz 4: Marka odtwarzacza audio w tablecie

Dla każdego urządzenia wypisz jego model, a następnie wynik przekazania go do funkcji StartPlayback.

Na przykład dla danych iPhone 15, Apple Audio, iPad Pro i Beats wynik powinien wyglądać następująco:

iPhone 15
Apple Audio playing audio
iPad Pro
Beats playing audio

Zwróć uwagę, że zarówno Smartphone, jak i Tablet można przekazać do funkcji StartPlayback, ponieważ metoda Play() z AudioPlayer jest automatycznie promowana do każdego typu zewnętrznego, dzięki czemu spełnia on wymagania interfejsu Playable bez dodatkowego kodu.

Spróbuj swoich sił

package main

import (
	"bufio"
	"fmt"
	"os"
)

// TODO: Utwórz funkcję StartPlayback, która przyjmuje dowolny obiekt Playable
// i zwraca wynik wywołania Play()

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Odczytaj model smartfona
	scanner.Scan()
	smartphoneModel := scanner.Text()
	
	// Odczytaj markę systemu audio smartfona
	scanner.Scan()
	smartphoneBrand := scanner.Text()
	
	// Odczytaj model tabletu
	scanner.Scan()
	tabletModel := scanner.Text()
	
	// Odczytaj markę systemu audio tabletu
	scanner.Scan()
	tabletBrand := scanner.Text()
	
	// TODO: Utwórz obiekt Smartphone z osadzonym AudioPlayer
	
	// TODO: Utwórz obiekt Tablet z osadzonym AudioPlayer
	
	// TODO: Wypisz model smartfona, a następnie wywołaj StartPlayback, przekazując smartfon
	
	// TODO: Wypisz model tabletu, a następnie wywołaj StartPlayback, przekazując tablet
	
	_ = smartphoneModel
	_ = smartphoneBrand
	_ = tabletModel
	_ = tabletBrand
	fmt.Println("TODO: Complete the implementation")
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Go online