Menu
CoddyTech

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 quando new() cria o objeto, com os argumentos fornecidos a new().
  • _ready() é executado quando um nó entra na árvore de cena, que é onde main.gd começ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 apagada

Um 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.

challenge icon

Desafio

Fácil

Escreva a classe Counter em counter.gd:

  • _init(start = 0, step_size = 1) armazena o início em value e o tamanho do passo em step. Os valores padrão já estão na assinatura, então Counter.new(), Counter.new(5) e Counter.new(5, 2) funcionam.
  • tick() adiciona step a value.
  • plus(other) substitui o operador +, que o GDScript não permite definir: ele retorna um Counter novo, cujo valor é a soma dos dois valores e cujo passo é o passo deste contador. Nenhum dos contadores é alterado.
  • equals(other) retorna true quando 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: false

Seu 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]))
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de GDScript online