Ukrywanie informacji
Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 28 z 65.
Ukrywanie informacji idzie o krok dalej niż zmienne prywatne: kod korzystający z klasy zależy wyłącznie od działania jej metod publicznych, nigdy od tego, jak klasa przechowuje swoje dane. Dzięki temu możesz zmienić sposób przechowywania danych bez modyfikowania tego kodu.
# inventory.gd
class_name Inventory
extends RefCounted
var _counts: Dictionary = {}
func add(item: String, amount: int) -> void:
_counts[item] = _counts.get(item, 0) + amount
func count(item: String) -> int:
return _counts.get(item, 0)
func remove(item: String, amount: int) -> bool:
if count(item) < amount:
return false
_counts[item] -= amount
return truemain.gd wywołuje add(), count() i remove() i nigdy nie widzi słownika. Jeśli później Inventory będzie przechowywać tablicę miejsc zamiast tego, zmieni się tylko inventory.gd.
Zachowaj ostrożność w przypadku getterów zwracających tablicę lub słownik. GDScript przekazuje te wartości przez referencję: wywołujący otrzymuje własną tablicę obiektu, a nie jej kopię, i może ją zmienić bez korzystania z metod klasy:
# quest_log.gd
var _quests: Array[String] = ["Find the key"]
func get_quests() -> Array[String]:
return _quests# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]Zwróć zamiast tego kopię. duplicate() tworzy nową tablicę z tymi samymi elementami, więc zmiany w niej pozostają poza obiektem:
func get_quests() -> Array[String]:
return _quests.duplicate()W przypadku słownika lub tablicy zawierającej inne tablice użyj duplicate(true): kopiuje ona również wewnętrzne tablice i słowniki.
Wyzwanie
ŁatwyNapisz klasę Playlist w pliku playlist.gd. Przechowuje ona tytuły utworów w prywatnej tablicy Array _songs, a pozostały kod korzysta wyłącznie z tych metod:
add(title)dodaje tytuł na końcu i zwracatrue. Jeśli tytuł znajduje się już na playliście, niczego nie zmienia i zwracafalse.remove(title)usuwa tytuł i zwracatruealbo zwracafalse, jeśli tytułu nie ma na liście.count()zwraca liczbę utworów.get_titles()zwraca kopię tytułów w kolejności, w jakiej zostały dodane.
Dostarczony kod odczytuje liczbę poleceń, a następnie po jednym poleceniu w każdym wierszu (add Blue Sky lub remove Blue Sky) i wyświetla wynik. Na końcu pobiera tablicę Array z get_titles(), dodaje do niej Intruder i odwraca jej kolejność, a następnie wyświetla liczbę utworów i tytuły. Te zmiany nie mogą wpłynąć na twoją playlistę. Dla poleceń add Blue Sky, add Rain i add Blue Sky program wyświetla:
Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, RainTwój kod umieść w pliku playlist.gd. Plik 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 playlist := Playlist.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ", true, 1)
var title := parts[1]
if parts[0] == "add":
if playlist.add(title):
print("Added: " + title)
else:
print("Already in the playlist: " + title)
elif playlist.remove(title):
print("Removed: " + title)
else:
print("Not found: " + title)
# Kod, który próbuje zmienić otrzymaną listę
var titles := playlist.get_titles()
titles.append("Intruder")
titles.reverse()
print("Songs: %d" % playlist.count())
print(", ".join(playlist.get_titles()))
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