Sistema Bancário
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 89 de 91.
Desafio
FácilVamos construir um Sistema Bancário que gerencia contas, transações e transferências entre contas. Você criará um sistema com encapsulamento adequado para proteger dados financeiros, herança para diferentes tipos de conta e validação para garantir a integridade dos dados.
Você organizará seu código em seis arquivos:
Transaction.php— Crie uma classeTransactionpara registrar operações financeiras. Use a promoção de construtor paratype(string — "deposit", "withdrawal", ou "transfer"),amount(float) etimestamp(string). Todas as propriedades devem ser public readonly. Adicione um métodogetDescription(): stringque retorna"[type]: $[amount]"(formate o valor com 2 casas decimais).BankAccount.php— Inclua o arquivo Transaction. Crie uma classe abstrataBankAccountcom:- Promoção de construtor para
accountNumber(string, public readonly) eholderName(string, public readonly) - Uma propriedade protegida
$balanceinicializada com 0.0 - Um array privado para armazenar o histórico de transações
getBalance(): float— retorna o saldo atualdeposit(float $amount): string— adiciona ao saldo, registra a transação, retorna"Deposited: $[amount]"abstract withdraw(float $amount): string— as classes filhas implementam as regras de saqueaddTransaction(Transaction $t): void— método protegido para adicionar transações ao históricogetTransactionCount(): int— retorna o número de transações
- Promoção de construtor para
SavingsAccount.php— Inclua o arquivo BankAccount. Crie uma classeSavingsAccountestendendoBankAccountcom:- Uma constante de classe
INTEREST_RATEdefinida como 0.02 (2%) withdraw(float $amount): string— se o valor exceder o saldo, retorne"Insufficient funds"; caso contrário, deduza, registre a transação e retorne"Withdrew: $[amount]"applyInterest(): string— calcula os juros sobre o saldo atual, adiciona-os como um depósito e retorna"Interest applied: $[interest]"
- Uma constante de classe
CheckingAccount.php— Inclua o arquivo BankAccount. Crie uma classeCheckingAccountestendendoBankAccountcom:- Uma propriedade privada
$overdraftLimitdefinida via construtor (adicione um terceiro parâmetro com o padrão 100.0) withdraw(float $amount): string— permite o saque se o valor não exceder o saldo + limite de cheque especial; retorne"Insufficient funds (overdraft limit: $[limit])"em caso de falha, ou"Withdrew: $[amount]"em caso de sucessogetOverdraftLimit(): float— retorna o limite do cheque especial
- Uma propriedade privada
Bank.php— Inclua ambos os arquivos de conta. Crie uma classeBankque gerencia as contas:- Um array privado para armazenar contas indexadas pelo número da conta
addAccount(BankAccount $account): void— adiciona uma contafindAccount(string $accountNumber): ?BankAccount— retorna a conta ou nulltransfer(string $fromAccount, string $toAccount, float $amount): string— transfere dinheiro entre contas. Retorne"Source account not found","Destination account not found", ou o resultado do saque se ele falhar. Em caso de sucesso, deposite no destino e retorne"Transferred $[amount] from [from] to [to]"
main.php— Inclua o arquivo Bank. Você receberá duas entradas: dados das contas (JSON) e operações (JSON).Formato JSON das Contas:
[{"type": "savings", "number": "SAV001", "holder": "Alice", "initial": 1000}, {"type": "checking", "number": "CHK001", "holder": "Bob", "initial": 500, "overdraft": 200}]Formato JSON das Operações:
[{"op": "deposit", "account": "SAV001", "amount": 200}, {"op": "withdraw", "account": "CHK001", "amount": 600}, {"op": "transfer", "from": "SAV001", "to": "CHK001", "amount": 300}, {"op": "interest", "account": "SAV001"}, {"op": "balance", "account": "SAV001"}]Crie o banco e todas as contas (depositando os valores iniciais). Processe cada operação:
"deposit"— Imprima o resultado dedeposit()"withdraw"— Imprima o resultado dewithdraw()"transfer"— Imprima o resultado detransfer()"interest"— Imprima o resultado deapplyInterest()(apenas para contas poupança)"balance"— Imprima"[holder] balance: $[balance]"(2 casas decimais)
Imprima cada resultado em uma nova linha. Formate todos os valores monetários com 2 casas decimais.
Lembre-se de que as transferências devem ser atômicas — se o saque falhar, o depósito não deve ocorrer. A propriedade protegida $balance permite que as classes filhas a modifiquem enquanto a mantêm oculta do código externo, demonstrando o encapsulamento adequado em um contexto financeiro.
Experimente você mesmo
<?php
require_once 'Bank.php';
// Ler a entrada
$accountsJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));
// Analisar as entradas JSON
$accounts = (array)json_decode($accountsJson, true);
$operations = (array)json_decode($operationsJson, true);
// TODO: Criar uma instância de Bank
// TODO: Criar contas a partir dos dados das contas
// Para cada conta em $accounts:
// - Se o tipo for "savings", criar SavingsAccount
// - Se o tipo for "checking", criar CheckingAccount (com cheque especial se fornecido)
// - Adicionar conta ao banco
// - Depositar valor inicial
// TODO: Processar cada operação
// Para cada operação em $operations:
// - "deposit": Imprimir resultado de deposit()
// - "withdraw": Imprimir resultado de withdraw()
// - "transfer": Imprimir resultado de transfer()
// - "interest": Imprimir resultado de applyInterest() (apenas para poupança)
// - "balance": Imprimir "[holder] balance: $[balance]" (2 casas decimais)
?>Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodoA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em DetalhesGetters e SettersOcultação de InformaçãoPromoção de Construtor (8.0)Recapitulação - Sistema de Registro de Alunos10Conceitos Avançados de POO
Composição vs HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibers (PHP 8.1)Mergulho Profundo em Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA Palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto Organizado5Interfaces e Contratos
Introdução a InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataType Hinting com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos AnuláveisTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadasTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário3Propriedades de Classe
Propriedades de Instância vs EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Readonly (PHP 8.1)Recapitulação - Gerenciador de Conta Bancária6Polimorfismo
Sobrescrita de Métodos RevisitadaPolimorfismo via InterfacesType Hinting e Union TypesLate Static BindingRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos de TraitsMétodos Abstratos em TraitsTraits vs Herança12Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy15Desafios Finais
Plataforma de E-LearningSistema BancárioDesenvolvimento de Personagens de JogosServiço de Aluguel de Veículos