Projektowanie interfejsów
Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 24 z 65.
Interfejs to lista metod, które klasa zobowiązuje się mieć, ale bez ich kodu. Java i C# mają słowo kluczowe interface; GDScript go nie ma. Tworzysz to samo za pomocą klasy abstrakcyjnej, której metody są wszystkie abstrakcyjne:
# drawable.gd
@abstract
class_name Drawable
extends RefCounted
@abstract func draw() -> String
@abstract func resize(factor: int) -> voidNie ma zmiennych ani treści metod. Opisuje, co może robić element, który da się narysować, a każda klasa sama o tym decyduje:
# banner.gd
class_name Banner
extends Drawable
var text: String
var size := 1
func _init(t: String) -> void:
text = t
func draw() -> String:
return "Banner '%s' at size %d" % [text, size]
func resize(factor: int) -> void:
size *= factorCircle również może rozszerzać Drawable, mając radius oraz własne metody draw() i resize(). Kod korzystający z interfejsu zależy tylko od niego, więc działa z każdą klasą rozszerzającą Drawable, także z tymi napisanymi później:
func render_all(items: Array[Drawable]) -> void:
for item in items:
item.resize(2)
print(item.draw())var items: Array[Drawable] = [Banner.new("Sale"), Circle.new(3)]
render_all(items)Banner 'Sale' at size 2
Circle with radius 6Klasa ma jednego rodzica, więc może rozszerzać tylko jeden interfejs. Gdy klasa pełni drugą rolę, na przykład jest zapisywana do pliku, rozszerz główny interfejs i sprawdź drugą rolę za pomocą has_method():
if item.has_method("save"):
item.save()Niech każdy interfejs będzie mały: kilka metod należących do jednej roli. Klasa, która go rozszerza, zapisuje wtedy tylko te metody, których potrzebuje.
Wyzwanie
ŁatwyZbuduj odtwarzacz multimediów oparty na interfejsie.
- W pliku
playable.gdutwórz interfejsPlayable: klasę abstrakcyjną z abstrakcyjnymi metodamiplay() -> Stringiduration() -> int(w sekundach). Songdziedziczy poPlayable.play()zwracaPlaying song: TITLE by ARTIST, aduration()zwraca liczbę sekund utworu.Videodziedziczy poPlayable.play()zwracaPlaying video: TITLE in RESOLUTIONp(na przykładin 1080p), aduration()zwraca liczbę sekund filmu.Playlistzna tylkoPlayable.play_all()wypisuje wynikplay()dla każdego elementu, atotal_time()zwraca łączny czas trwania w formacieM:SS(sekundy zapisane za pomocą dwóch cyfr, na przykład4:05).
Konstruktory Song i Video są już napisane. Dostarczony kod odczytuje liczbę kolejnych elementów, a następnie po jednym wierszu na element: song TITLE ARTIST SECONDS lub video TITLE RESOLUTION SECONDS. Wywołuje play_all() i wypisuje łączny czas. Dla song Imagine Lennon 183 i video Trailer 1080 95 wypisuje:
Playing song: Imagine by Lennon
Playing video: Trailer in 1080p
Total time: 4:38Twój kod umieść w plikach playable.gd, song.gd, video.gd i playlist.gd. main.gd zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
extends Node
func _ready():
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
var count := int(OS.read_string_from_stdin())
var playlist := Playlist.new()
for i in count:
var p := OS.read_string_from_stdin().split(" ")
if p[0] == "song":
playlist.add(Song.new(p[1], p[2], int(p[3])))
else:
playlist.add(Video.new(p[1], int(p[2]), int(p[3])))
playlist.play_all()
print("Total time: " + playlist.total_time())
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe selfMetodyWłaściwościKonstruktor (_init)Powtórka – prosty kalkulator4Polimorfizm
Ponowne omówienie przesłaniania metodDuck typingKlasy i metody abstrakcyjneProjektowanie interfejsówPowtórzenie – kalkulator kształtów7Sygnały
Czym jest sygnał?Deklarowanie i emitowanieŁączenie z sygnałamiSygnały z argumentamiPodsumowanie — system zdrowia10Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu2Właściwości klas
Zmienne instancji a zmienne statyczneFunkcje statyczneSettery właściwościGettery właściwościPrywatne z konwencjiPodsumowanie — menedżer kont bankowych5Enkapsulacja
Elementy publiczne i prywatneWalidacja za pomocą setterówUkrywanie informacjiWłaściwości tylko do odczytuPodsumowanie – system ewidencji uczniów8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieKlasy wewnętrzneWęzły jako komponentyRefCounted a NodeTypy wyliczeniowe w klasach11Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superNadpisywanie metodŁańcuchy dziedziczeniaSprawdzanie typów za pomocą isPodsumowanie – hierarchia pracowników6Metody specjalne
Wprowadzenie do metod wirtualnychMetoda _to_stringWłasne iteratoryPodsumowanie — własna lista9Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec StrategyPoćwicz samodzielnie: Kompilator GDScript online