Abstrakte Klassen und Methoden
Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 23 von 65.
Manche Klassen existieren nur, um erweitert zu werden. Jede Form hat eine Fläche, aber du kannst sie erst berechnen, wenn du weißt, ob die Form ein Kreis oder ein Rechteck ist. Markiere eine solche Klasse mit @abstract in der Zeile über 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()]Eine @abstract func hat eine Signatur und keinen Rumpf: keinen Doppelpunkt und keinen Code danach. Sie besagt, dass jede Unterklasse diese Methode bereitstellen muss. describe() ist eine normale Methode; Unterklassen erben sie, und sie kann bereits die abstrakten Methoden aufrufen.
Du kannst kein Objekt einer abstrakten Klasse erstellen. Shape.new() stoppt das Programm, bevor es startet, mit Parse Error: Cannot construct abstract class "Shape".
Eine abgeleitete Klasse, die jede abstrakte Methode implementiert, ist eine normale Klasse:
# 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.0Wenn ein Kind eines davon weglässt, meldet Godot dies vor der Ausführung: Class "Square" must implement "Shape.perimeter()" and other inherited abstract methods or be marked as "@abstract". Somit hat jedes Objekt, das du erstellen kannst, area() und perimeter().
Eine abstrakte Klasse kann trotzdem Variablen und ein _init() haben. Unterklassen rufen sie wie üblich mit super() auf.
Aufgabe
EinfachEin Geschäft akzeptiert zwei Zahlungsmethoden. Jede Zahlung hat einen Betrag und einen Beleg, aber die Gebühr und der Name hängen von der Methode ab.
- Mache
PaymentMethodabstrakt und deklariere zwei abstrakte Methoden:fee() -> floatundmethod_name() -> String. Schreibereceipt(), dasNAME: paid AMOUNT, fee FEE, total TOTALmit zwei Dezimalstellen für jede Zahl zurückgibt (die Gesamtsumme ist der Betrag zuzüglich der Gebühr). CreditCard: Die Gebühr beträgt 3 % des Betrags (amount * 0.03), und der Name istCredit card.BankTransfer: Die Gebühr beträgt1.5oder0.0, wenn der Betrag100oder mehr beträgt, und der Name istBank transfer.
Die Kindklassen verwenden den Konstruktor von PaymentMethod. Der bereitgestellte Code liest ein, wie viele Zahlungen folgen, dann eine Zeile pro Zahlung: card AMOUNT oder transfer AMOUNT. Er gibt jeden Beleg und die Summe der Gebühren aus. Für card 50 und transfer 120 gibt er Folgendes aus:
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.50Dein Code gehört in payment_method.gd, credit_card.gd und bank_transfer.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
extends Node
func _ready():
# Vorgegebener Eingabe-/Ausgabecode: unverändert lassen
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)
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort selfMethodenEigenschaftenKonstruktor (_init)Wiederholung – Einfacher Taschenrechner4Polymorphie
Methodenüberschreibung erneut betrachtetDuck-TypisierungAbstrakte Klassen und MethodenSchnittstellendesignRückblick – Formrechner2Klassenattribute
Instanz- vs. statische VariablenStatische FunktionenProperty-SetterProperty-GetterPrivat nach KonventionWiederholung – Bankkontenverwaltung5Kapselung
Öffentliche und private MemberValidierung mit SetternInformationsverbergenSchreibgeschützte EigenschaftenRückblick – System zur Schülerverwaltung8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungInnere KlassenNodes als KomponentenRefCounted vs. NodeEnums in Klassen11Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungVererbungskettenTypprüfungen mit isWiederholung – Mitarbeiterhierarchie6Spezielle Methoden
Einführung in virtuelle MethodenDie _to_string-MethodeBenutzerdefinierte IteratorenRückblick – Benutzerdefinierte Liste9Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBeobachter-MusterStrategie-Muster12Abschließende Herausforderungen
E-Learning-PlattformBankensystemEntwicklung von SpielfigurenFahrzeugvermietungÜbe selbstständig: Online-GDScript-Compiler