Menu
CoddyTech

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

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

challenge icon

Aufgabe

Einfach

Ein 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 PaymentMethod abstrakt und deklariere zwei abstrakte Methoden: fee() -> float und method_name() -> String. Schreibe receipt(), das NAME: paid AMOUNT, fee FEE, total TOTAL mit 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 ist Credit card.
  • BankTransfer: Die Gebühr beträgt 1.5 oder 0.0, wenn der Betrag 100 oder mehr beträgt, und der Name ist Bank 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.50

Dein 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)
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-GDScript-Compiler