Introduction aux méthodes virtuelles
Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 31 sur 65.
Python possède des méthodes magiques telles que __init__ et __str__, que le langage appelle pour vous. Dans Godot, leur équivalent est la méthode virtuelle : une méthode portant un nom fixe, commençant par un trait de soulignement, que vous définissez dans votre classe et que Godot appelle au bon moment. Vous en avez déjà utilisé deux :
_init()s’exécute lorsquenew()crée l’objet, avec les arguments transmis ànew()._ready()s’exécute lorsqu’un nœud entre dans l’arbre de scène, là oùmain.gdcommence.
D’autres sont _to_string(), appelé lorsqu’un objet est affiché, les méthodes d’itérateur qui permettent à une boucle for de parcourir un objet (dans les deux prochaines leçons), et _notification(), qui reçoit des événements du moteur. L’un d’eux, NOTIFICATION_PREDELETE, est envoyé juste avant la suppression de l’objet :
# 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") # Torche du hall allumée
torch = null # Torche du hall éteinteUn objet RefCounted est supprimé dès qu’aucune variable ne le référence plus, donc torch = null envoie la notification immédiatement. La valeur par défaut dans _init() rend l’argument de new() facultatif : Torch.new() crée une torche appelée Torch.
Python utilise également des méthodes magiques pour les opérateurs, comme __add__ pour + et __eq__ pour ==. GDScript ne prend pas en charge la surcharge des opérateurs : potion_a + potion_b est une erreur. Écris plutôt une méthode :
# 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) renvoie une nouvelle potion et laisse les deux originales inchangées. == entre deux objets vérifie si les deux côtés sont le même objet, et non si leurs valeurs correspondent : Potion.new(5) == Potion.new(5) est false. Écris une méthode telle que equals(other) lorsque tu as besoin de comparer des valeurs.
Défi
FacileÉcris la classe Counter dans counter.gd :
_init(start = 0, step_size = 1)stocke la valeur de départ dansvalueet le pas dansstep. Les valeurs par défaut figurent déjà dans la signature, doncCounter.new(),Counter.new(5)etCounter.new(5, 2)fonctionnent tous.tick()ajoutestepàvalue.plus(other)remplace l’opérateur+, que GDScript ne permet pas de définir : il renvoie un nouveauCounterdont la valeur est la somme des deux valeurs et dont le pas est celui de ce compteur. Aucun des deux compteurs ne change.equals(other)renvoietruelorsque les deux compteurs ont la même valeur.
Le code fourni lit deux lignes qui créent les compteurs a et b (une ligne vide, START ou START STEP), puis une ligne indiquant combien de fois incrémenter a et b. Il affiche les deux compteurs, leur somme, si leurs valeurs sont égales et si a == b. Pour les lignes 5, 2 3 et 3 1, il affiche :
a: 8 (step 1)
b: 5 (step 3)
a plus b: 13 (step 1)
same value: false
same object: falseTon code doit être placé dans counter.gd. main.gd contient le code fourni pour les entrées et sorties et ne peut pas être modifié.
Essayez vous-même
extends Node
func _ready():
# Code d’entrée/sortie fourni : conservez-le tel quel
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]))
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé selfMéthodesPropriétésConstructeur (_init)Récapitulatif - Calculatrice simple4Polymorphisme
Retour sur la redéfinition des méthodesTypage canardClasses et méthodes abstraitesConception d’interfacesRécapitulatif – Calculateur de formes7Signaux
Qu’est-ce qu’un signal ?Déclarer et émettreSe connecter aux signauxSignaux avec argumentsRécapitulatif - système de santé10Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron Composite2Propriétés de classe
Variables d’instance et variables statiquesFonctions statiquesSetters de propriétésGetters de propriétésPrivé par conventionRécapitulatif - Gestionnaire de comptes bancaires5Encapsulation
Membres publics et privésValidation avec les méthodes setterMasquage de l’informationPropriétés en lecture seuleRécapitulatif - Système de dossiers étudiants8Concepts avancés de la POO
Composition ou héritageClasses internesLes nœuds comme composantsRefCounted ou NodeEnums dans les classes3Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodesChaînes d’héritageVérifier les types avec isRécapitulatif – Hiérarchie des employés6Méthodes spéciales
Introduction aux méthodes virtuellesLa méthode _to_stringItérateurs personnalisésRécapitulatif – Liste personnalisée9Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur GDScript en ligne