Ocultação de informações
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 28 de 65.
Ocultação de informações vai um passo além das variáveis privadas: o código que usa uma classe depende apenas do que seus métodos públicos fazem, nunca de como a classe armazena seus dados. Assim, você pode alterar o armazenamento sem tocar nesse código.
# 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 chama add(), count() e remove() e nunca vê o Dictionary. Se Inventory passar a manter um Array de espaços em vez disso, somente inventory.gd será alterado.
Tenha cuidado com getters que retornam um Array ou um Dictionary. O GDScript fornece esses valores por referência: quem chama recebe o próprio Array do objeto, não uma cópia, e pode alterá-lo sem passar pelos métodos da classe:
# 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"]Retorne uma cópia. duplicate() cria um novo Array com os mesmos elementos, então as alterações nele ficam fora do objeto:
func get_quests() -> Array[String]:
return _quests.duplicate()Para um Dictionary ou um Array que contém outros Arrays, use duplicate(true): ele também copia os Arrays e os Dictionaries internos.
Desafio
FácilEscreva a classe Playlist em playlist.gd. Ela mantém os títulos das músicas no Array privado _songs, e outros códigos usam apenas estes métodos:
add(title)acrescenta o título e retornatrue. Se o título já estiver na playlist, não altera nada e retornafalse.remove(title)remove o título e retornatrue, ou retornafalsequando ele não está na playlist.count()retorna o número de músicas.get_titles()retorna uma cópia dos títulos, na ordem em que foram adicionados.
O código fornecido lê o número de comandos e, em seguida, um comando por linha (add Blue Sky ou remove Blue Sky) e imprime o resultado. No final, ele obtém o Array de get_titles(), acrescenta Intruder e o inverte, depois imprime a quantidade de músicas e os títulos. Sua playlist não deve ser afetada por essas alterações. Para os comandos add Blue Sky, add Rain e add Blue Sky, imprime:
Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, RainSeu código deve ficar em playlist.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
extends Node
func _ready():
# Código de entrada/saída fornecido: mantenha-o como está
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)
# Código que tenta alterar a lista que recebe de volta
var titles := playlist.get_titles()
titles.append("Intruder")
titles.reverse()
print("Songs: %d" % playlist.count())
print(", ".join(playlist.get_titles()))
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Fundamentos da POO
Arquivos externosIntrodução à POOClasses vs. objetosA palavra-chave selfMétodosPropriedadesConstrutor (_init)Revisão - Calculadora simples4Polimorfismo
Revisitando a Sobrescrita de MétodosDuck TypingClasses e Métodos AbstratosDesign de InterfacesRevisão - Calculadora de Formas7Sinais
O que é um sinal?Declarando e emitindoConectando-se a sinaisSinais com argumentosRevisão - Sistema de saúde10Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite2Propriedades de Classe
Variáveis de Instância vs. EstáticasFunções EstáticasMétodos Setters de PropriedadeMétodos Getters de PropriedadePrivado por ConvençãoRecapitulando: Gerenciador de Conta Bancária5Encapsulamento
Membros públicos e privadosValidação com settersOcultação de informaçõesPropriedades somente para leituraRevisão - Sistema de registros de alunos8Conceitos Avançados de POO
Composição vs. HerançaClasses InternasNós como ComponentesRefCounted vs. NodeEnums em Classes3Herança
Herança básicaA palavra-chave superSobrescrita de métodosCadeias de herançaVerificações de tipo com isRevisão - Hierarquia de funcionários6Métodos especiais
Introdução aos métodos virtuaisO método _to_stringIteradores personalizadosRevisão - Lista personalizada9Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de GDScript online