Classes et méthodes abstraites
Fait partie de la section Programmation orientée objet du Journey GDScript de Coddy. Leçon 23 sur 65.
Certaines classes existent uniquement pour être étendues. Chaque forme a une aire, mais vous ne pouvez pas la calculer tant que vous ne savez pas s’il s’agit d’un cercle ou d’un rectangle. Marquez une telle classe avec @abstract, sur la ligne au-dessus de class_name :
# shape.gd
@abstract
class_name Shape
extends RefCounted
@abstract func area() -> float
@abstract func perimeter() -> float
func describe() -> String:
return "Area %.1f, perimeter %.1f" % [area(), perimeter()]Un @abstract func possède une signature et aucun corps : pas de deux-points ni de code après lui. Cela signifie que chaque classe enfant doit fournir cette méthode. describe() est une méthode normale ; les classes enfants en héritent, et elle peut déjà appeler les méthodes abstraites.
Tu ne peux pas créer d’objet d’une classe abstraite. Shape.new() arrête le programme avant son démarrage avec Parse Error: Cannot construct abstract class "Shape".
Une classe enfant qui écrit toutes les méthodes abstraites est une classe normale :
# rectangle.gd
class_name Rectangle
extends Shape
var width: float
var height: float
func _init(w: float, h: float) -> void:
width = w
height = h
func area() -> float:
return width * height
func perimeter() -> float:
return 2 * (width + height)var rect := Rectangle.new(4.0, 6.0)
print(rect.describe())Area 24.0, perimeter 20.0Si une classe enfant en omet une, Godot le signale avant l’exécution : Class "Square" must implement "Shape.perimeter()" and other inherited abstract methods or be marked as "@abstract". Ainsi, chaque objet que tu peux créer possède area() et perimeter().
Une classe abstraite peut tout de même avoir des variables et un _init(). Les classes enfants l’appellent avec super() comme d’habitude.
Défi
FacileUne boutique accepte deux modes de paiement. Chaque paiement comporte un montant et un reçu, mais les frais et le nom dépendent du mode.
- Faites de
PaymentMethodune classe abstraite et déclarez deux méthodes abstraites :fee() -> floatetmethod_name() -> String. Écrivezreceipt(), qui renvoieNAME: paid AMOUNT, fee FEE, total TOTALavec deux décimales pour chaque nombre (le total correspond au montant plus les frais). CreditCard: les frais correspondent à 3 % du montant (amount * 0.03), et le nom estCredit card.BankTransfer: les frais sont de1.5, ou de0.0lorsque le montant est supérieur ou égal à100, et le nom estBank transfer.
Les classes dérivées utilisent le constructeur de PaymentMethod. Le code fourni lit le nombre de paiements à venir, puis une ligne par paiement : card AMOUNT ou transfer AMOUNT. Il affiche chaque reçu et la somme des frais. Pour card 50 et transfer 120, il affiche :
Credit card: paid 50.00, fee 1.50, total 51.50
Bank transfer: paid 120.00, fee 0.00, total 120.00
Total fees: 1.50Votre code doit être placé dans payment_method.gd, credit_card.gd et bank_transfer.gd. main.gd contient le code fourni pour les entrées/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 count := int(OS.read_string_from_stdin())
var total_fees := 0.0
for i in count:
var p := OS.read_string_from_stdin().split(" ")
var payment: PaymentMethod
if p[0] == "card":
payment = CreditCard.new(float(p[1]))
else:
payment = BankTransfer.new(float(p[1]))
print(payment.receipt())
total_fees += payment.fee()
print("Total fees: %.2f" % total_fees)
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