Introdução aos métodos virtuais
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 31 de 65.
Python tem métodos mágicos, como __init__ e __str__, que a linguagem chama para você. A versão do Godot é o método virtual: um método com um nome fixo, que começa com um sublinhado, que você define na sua classe e que o Godot chama no momento certo. Você já usou dois:
_init()é executado quandonew()cria o objeto, com os argumentos fornecidos anew()._ready()é executado quando um nó entra na árvore de cena, que é ondemain.gdcomeça.
Outros são _to_string(), chamado quando um objeto é impresso, os métodos iteradores que permitem que um loop for percorra um objeto (ambos nas próximas lições) e _notification(), que recebe eventos do mecanismo. Um deles, NOTIFICATION_PREDELETE, ocorre logo antes de o objeto ser excluído:
# torch.gd
class_name Torch
extends RefCounted
var label: String
func _init(new_label: String = "Torch") -> void:
label = new_label
print(label, " lit")
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
print(label, " burned out")# main.gd
var torch := Torch.new("Hall torch") # Tocha do corredor acesa
torch = null # Tocha do corredor apagadaUm objeto RefCounted é excluído assim que nenhuma variável mais se refere a ele, então torch = null envia a notificação imediatamente. O valor padrão em _init() torna o argumento de new() opcional: Torch.new() cria uma tocha chamada Torch.
Python também usa métodos mágicos para operadores, como __add__ para + e __eq__ para ==. GDScript não tem sobrecarga de operadores: potion_a + potion_b é um erro. Escreva um método em vez disso:
# potion.gd
class_name Potion
extends RefCounted
var power: int
func _init(start_power: int) -> void:
power = start_power
func combined(other: Potion) -> Potion:
return Potion.new(power + other.power)potion_a.combined(potion_b) retorna uma nova poção e deixa ambas as originais inalteradas. == entre dois objetos verifica se ambos os lados são o mesmo objeto, não se seus valores correspondem: Potion.new(5) == Potion.new(5) é false. Escreva um método como equals(other) quando precisar comparar valores.
Desafio
FácilEscreva a classe Counter em counter.gd:
_init(start = 0, step_size = 1)armazena o início emvaluee o tamanho do passo emstep. Os valores padrão já estão na assinatura, entãoCounter.new(),Counter.new(5)eCounter.new(5, 2)funcionam.tick()adicionastepavalue.plus(other)substitui o operador+, que o GDScript não permite definir: ele retorna umCounternovo, cujo valor é a soma dos dois valores e cujo passo é o passo deste contador. Nenhum dos contadores é alterado.equals(other)retornatruequando os dois contadores têm o mesmo valor.
O código fornecido lê duas linhas que criam os contadores a e b (uma linha vazia, START ou START STEP) e, em seguida, uma linha com o número de vezes que a e b devem avançar. Ele imprime os dois contadores, a soma deles, se os valores são iguais e se a == b. Para as linhas 5, 2 3 e 3 1, ele imprime:
a: 8 (step 1)
b: 5 (step 3)
a plus b: 13 (step 1)
same value: false
same object: falseSeu código deve estar em counter.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 a := make_counter(OS.read_string_from_stdin())
var b := make_counter(OS.read_string_from_stdin())
var ticks := OS.read_string_from_stdin().split(" ")
for i in int(ticks[0]):
a.tick()
for i in int(ticks[1]):
b.tick()
print("a: %d (step %d)" % [a.value, a.step])
print("b: %d (step %d)" % [b.value, b.step])
var total := a.plus(b)
print("a plus b: %d (step %d)" % [total.value, total.step])
print("same value: %s" % a.equals(b))
print("same object: %s" % (a == b))
func make_counter(line: String) -> Counter:
var parts := line.split(" ", false)
if parts.is_empty():
return Counter.new()
if parts.size() == 1:
return Counter.new(int(parts[0]))
return Counter.new(int(parts[0]), int(parts[1]))
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