Classes e Métodos Abstratos
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 23 de 65.
Algumas classes existem apenas para serem estendidas. Toda forma tem uma área, mas você não pode calculá-la até saber se a forma é um círculo ou um retângulo. Marque essa classe como @abstract, na linha acima 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()]Uma @abstract func tem uma assinatura e nenhum corpo: nenhum dois-pontos e nenhum código depois dela. Isso significa que cada classe filha deve fornecer esse método. describe() é um método normal; as classes filhas o herdam, e ele já pode chamar os métodos abstratos.
Você não pode criar um objeto de uma classe abstrata. Shape.new() interrompe o programa antes que ele comece com Parse Error: Cannot construct abstract class "Shape".
Uma classe filha que implementa todos os métodos abstratos é uma classe normal:
# 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.0Se uma classe derivada deixar de implementar algum deles, o Godot informa isso antes de executar: Class "Square" must implement "Shape.perimeter()" and other inherited abstract methods or be marked as "@abstract". Assim, todo objeto que você pode criar tem area() e perimeter().
Uma classe abstrata ainda pode ter variáveis e um _init(). As classes filhas o chamam com super(), como de costume.
Desafio
FácilUma loja aceita dois métodos de pagamento. Cada pagamento tem um valor e um recibo, mas a taxa e o nome dependem do método.
- Defina
PaymentMethodcomo abstrata e declare dois métodos abstratos:fee() -> floatemethod_name() -> String. Escrevareceipt(), que retornaNAME: paid AMOUNT, fee FEE, total TOTALcom duas casas decimais para cada número (o total é o valor mais a taxa). CreditCard: a taxa é 3% do valor (amount * 0.03), e o nome éCredit card.BankTransfer: a taxa é1.5, ou0.0quando o valor é100ou mais, e o nome éBank transfer.
As classes filhas usam o construtor de PaymentMethod. O código fornecido lê quantos pagamentos vêm em seguida e, depois, uma linha por pagamento: card AMOUNT ou transfer AMOUNT. Ele imprime cada recibo e a soma das taxas. Para card 50 e transfer 120, ele imprime:
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.50Seu código deve ficar em payment_method.gd, credit_card.gd e bank_transfer.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
extends Node
func _ready():
# Código de entrada/saída fornecido: mantenha-o como está
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)
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Fundamentos da POO
Arquivos externosIntrodução à POOClasses vs. objetosA palavra-chave selfMétodosPropriedadesConstrutor (_init)Revisão - Calculadora simples4Polimorfismo
Revisitando a Sobrescrita de MétodosDuck TypingClasses e Métodos AbstratosDesign de InterfacesRevisão - Calculadora de Formas7Sinais
O que é um sinal?Declarando e emitindoConectando-se a sinaisSinais com argumentosRevisão - Sistema de saúde10Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite2Propriedades de Classe
Variáveis de Instância vs. EstáticasFunções EstáticasMétodos Setters de PropriedadeMétodos Getters de PropriedadePrivado por ConvençãoRecapitulando: Gerenciador de Conta Bancária5Encapsulamento
Membros públicos e privadosValidação com settersOcultação de informaçõesPropriedades somente para leituraRevisão - Sistema de registros de alunos8Conceitos Avançados de POO
Composição vs. HerançaClasses InternasNós como ComponentesRefCounted vs. NodeEnums em Classes3Herança
Herança básicaA palavra-chave superSobrescrita de métodosCadeias de herançaVerificações de tipo com isRevisão - Hierarquia de funcionários6Métodos especiais
Introdução aos métodos virtuaisO método _to_stringIteradores personalizadosRevisão - Lista personalizada9Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de GDScript online