추상 클래스와 메서드
Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 23번째.
일부 클래스는 확장하기 위한 목적으로만 존재합니다. 모든 도형에는 넓이가 있지만, 그 도형이 원인지 직사각형인지 알기 전까지는 넓이를 계산할 수 없습니다. 이러한 클래스는 class_name 줄 바로 위에 @abstract를 표시하세요:
# 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()]@abstract func에는 시그니처만 있고 본문은 없습니다. 콜론도 없고 그 뒤에 코드도 없습니다. 이는 모든 자식 클래스가 이 메서드를 구현해야 한다는 뜻입니다. describe()는 일반 메서드입니다. 자식 클래스는 이 메서드를 상속하며, 이 메서드는 추상 메서드를 이미 호출할 수 있습니다.
추상 클래스의 객체는 생성할 수 없습니다. Shape.new()는 프로그램이 시작되기 전에 Parse Error: Cannot construct abstract class "Shape". 오류와 함께 프로그램을 중단합니다.
모든 추상 메서드를 작성하는 자식 클래스는 일반 클래스입니다:
# 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자식 클래스가 하나를 빠뜨리면 Godot는 실행 전에 다음과 같이 알려 줍니다. Class "Square" must implement "Shape.perimeter()" and other inherited abstract methods or be marked as "@abstract". 따라서 생성할 수 있는 모든 객체에는 area()와 perimeter()가 있습니다.
추상 클래스에도 변수와 _init()이 있을 수 있습니다. 자식 클래스는 평소처럼 super()를 사용해 이를 호출합니다.
챌린지
쉬움상점은 두 가지 결제 방법을 지원합니다. 모든 결제에는 금액과 영수증이 있지만, 수수료와 이름은 결제 방법에 따라 다릅니다.
PaymentMethod를 추상 클래스로 만들고 추상 메서드 두 개를 선언하세요:fee() -> float와method_name() -> String.receipt()를 작성하세요. 이 메서드는 각 숫자를 소수점 이하 두 자리로 표시하여NAME: paid AMOUNT, fee FEE, total TOTAL을 반환합니다(합계는 금액에 수수료를 더한 값입니다).CreditCard: 수수료는 금액의 3%이며(amount * 0.03), 이름은Credit card입니다.BankTransfer: 수수료는1.5이며, 금액이100이상이면0.0입니다. 이름은Bank transfer입니다.
자식 클래스는 PaymentMethod의 생성자를 사용합니다. 제공된 코드는 결제 건수를 읽은 다음 각 결제마다 한 줄씩 읽습니다: card AMOUNT 또는 transfer AMOUNT. 모든 영수증과 수수료의 합계를 출력합니다. card 50과 transfer 120을 입력하면 다음을 출력합니다:
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코드는 payment_method.gd, credit_card.gd, bank_transfer.gd에 작성하세요. main.gd에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.
직접 해보기
extends Node
func _ready():
# 제공된 입출력 코드: 그대로 유지하세요
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)
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 GDScript 컴파일러