Menu
Coddy logo textTech

Bankacılık Sistemi

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 85 / 87.

Bu meydan okuma, OOP prensiplerini kullanarak gerçek dünyadaki finansal işlemleri modelleyen bir Bankacılık Sistemi oluşturmanızı hedeflemektedir.

Sisteminiz, her ikisi de temel bir Account sınıfını genişleten SavingsAccount ve CheckingAccount gibi farklı hesap türlerini yönetmelidir. Her hesap türünün kendine özgü davranışları vardır: birikim hesapları faiz getirebilirken, vadesiz hesapların kredili mevduat koruması olabilir.

İşlemlerin nasıl modelleneceğini düşünün. Transactable gibi bir arayüz, deposit() ve withdraw() için metotlar tanımlayabilir. Geçersiz işlemleri düzgün bir şekilde ele almak için InsufficientFundsException gibi özel istisnalar kullanmayı düşünün.

Bir Bank class'ı, kompozisyon (composition) sergileyerek birden fazla hesabı ve müşteriyi yönetebilir. Farklı hesap türleri oluşturmak için Factory desenini uygulayabilir veya müşterileri hesap değişikliklerinden haberdar etmek için Observer desenini kullanabilirsiniz.

Bakiyeler ve hesap numaraları gibi hassas verileri korumak için kapsüllemeye (encapsulation) odaklanın ve farklı hesap türlerini tek tipte işlemek için çok biçimliliği (polymorphism) kullanın.

challenge icon

Görev

Kolay

OOP prensiplerindeki ustalığınızı gösterecek eksiksiz bir Bankacılık Sistemi inşa edelim! Farklı hesap türleri, işlem yönetimi ve uygun istisna (exception) yönetimi içeren, birden fazla dosyaya yayılmış bir sistem oluşturacaksınız.

Kodunuzu yedi dosya halinde düzenleyeceksiniz:

  • Transactable.java: Finansal işlemler için sözleşmeyi tanımlayan bir arayüz (interface) oluşturun. Başarı durumunu belirtmek için her ikisi de boolean döndüren deposit(double amount) ve withdraw(double amount) metotlarını bildirmelidir.
  • InsufficientFundsException.java: Exception sınıfını genişleten özel bir istisna oluşturun. Kurucu (constructor), denenen çekim miktarını ve mevcut bakiyeyi kabul etmeli ve "Insufficient funds: attempted %.2f, available %.2f" formatında bir mesaj oluşturmalıdır.
  • Account.java: Herhangi bir banka hesabını temsil eden soyut (abstract) bir temel sınıf oluşturun. accountNumber (String) ve balance (double) için private alanlar, her ikisini de başlatan bir kurucu, uygun getter metotları, bakiyenin alt sınıflar tarafından değiştirilebilmesi için protected bir setter ve String döndüren soyut bir getAccountType() metodu ekleyin. Bakiyeyi 2 ondalık basamakla formatlayarak "%s (%s): $%.2f" döndüren bir getDetails() metodu uygulayın.
  • SavingsAccount.java: Account sınıfını genişleten ve Transactable arayüzünü uygulayan bir sınıf oluşturun. interestRate (double) için private bir alan ekleyin. Kurucu; accountNumber, başlangıç bakiyesi ve interestRate alır. getAccountType() metodunu "Savings" döndürecek şekilde uygulayın. deposit() için miktarı bakiyeye ekleyin ve true döndürün. withdraw() için miktar bakiyeyi aşarsa false döndürün; aksi takdirde miktarı çıkarın ve true döndürün. Bakiyeyi faiz oranı yüzdesi kadar artıran bir applyInterest() metodu ekleyin.
  • CheckingAccount.java: Account sınıfını genişleten ve Transactable arayüzünü uygulayan bir sınıf oluşturun. overdraftLimit (double) için private bir alan ekleyin. Kurucu; accountNumber, başlangıç bakiyesi ve overdraftLimit alır. getAccountType() metodunu "Checking" döndürecek şekilde uygulayın. deposit() için miktarı ekleyin ve true döndürün. withdraw() için miktar, bakiye artı overdraftLimit toplamına eşit veya daha azsa çekime izin verin; bu sınırı aşarsa false döndürün.
  • Bank.java: Hesapları bir ArrayList kullanarak yöneten bir sınıf oluşturun. Şu metotları içermelidir:
    • addAccount(Account account) - bankaya bir hesap ekler
    • findAccount(String accountNumber) - hesabı döndürür veya bulunamazsa null döndürür
    • transfer(String fromAccount, String toAccount, double amount) - hesaplar arasında para transferi yapar, kaynak hesapta yetersiz bakiye varsa InsufficientFundsException fırlatır. Başarılı olduğunda "Transferred $%.2f from %s to %s" döndürür.
    • getTotalDeposits() - tüm hesap bakiyelerinin toplamını döndürür
  • Main.java: Bankacılık sisteminizi kurun! Virgülle ayrılmış bir komut dizisi alacaksınız:
    • SAVINGS:accountNumber:balance:interestRate
    • CHECKING:accountNumber:balance:overdraftLimit
    • DEPOSIT:accountNumber:amount
    • WITHDRAW:accountNumber:amount
    • TRANSFER:fromAccount:toAccount:amount
    • INTEREST:accountNumber

    Her komutu işleyin ve şunları yazdırın:

    • SAVINGS/CHECKING: "Account created: " + accountNumber
    • DEPOSIT: "Deposited $%.2f to %s%n"
    • WITHDRAW: Başarılıysa "Withdrew $%.2f from %s%n", değilse "Withdrawal failed: " + accountNumber
    • TRANSFER: Başarı mesajını veya "Transfer failed: " + e.getMessage() yazdırın
    • INTEREST: "Interest applied to " + accountNumber

    Tüm komutlardan sonra, "--- Bank Summary ---" yazdırın, ardından her hesabın detaylarını (getDetails() kullanarak) ve son olarak 2 ondalık basamakla formatlanmış "Total deposits: $%.2f%n" yazdırın.

Bir girdi alacaksınız: virgülle ayrılmış komut dizisi.

Örneğin, SAVINGS:SAV001:1000.00:0.05,CHECKING:CHK001:500.00:200.00,DEPOSIT:SAV001:250.00,WITHDRAW:CHK001:600.00,TRANSFER:SAV001:CHK001:100.00,INTEREST:SAV001 girdisi ile çıktınız şöyle olacaktır:

Account created: SAV001
Account created: CHK001
Deposited $250.00 to SAV001
Withdrew $600.00 from CHK001
Transferred $100.00 from SAV001 to CHK001
Interest applied to SAV001
--- Bank Summary ---
SAV001 (Savings): $1207.50
CHK001 (Checking): $0.00
Total deposits: $1207.50

Vadesiz hesabın (checking account), sadece $500 bakiyesi olmasına rağmen $600 çekime nasıl izin verdiğine dikkat edin—bu, kredili mevduat korumasının (overdraft protection) iş başındaki halidir! Tasarruf hesabı (savings account), transferden sonraki bakiyesi üzerinden %5 faiz kazanır. Bu meydan okuma; kalıtım, arayüzler, polimorfizm, özel istisnalar ve kapsüllemeyi gerçekçi bir bankacılık uygulamasında birleştiriyor!

Kopya kağıdı

Bir Banka Sistemi; hesap yönetimi, işlemler ve istisna yönetimi aracılığıyla OOP prensiplerini gösterir.

Sözleşmeler için Arayüzler

Arayüzleri kullanarak ortak işlemleri tanımlayın:

public interface Transactable {
    boolean deposit(double amount);
    boolean withdraw(double amount);
}

Özel İstisnalar

Alana özgü hatalar için özel istisnalar oluşturun:

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(double attempted, double available) {
        super("Insufficient funds: attempted " + attempted + ", available " + available);
    }
}

Soyut Temel Sınıflar

Alt sınıfa özgü davranışlar için soyut yöntemlerle ortak yapıyı tanımlamak üzere soyut sınıfları kullanın:

public abstract class Account {
    private String accountNumber;
    private double balance;
    
    public abstract String getAccountType();
    
    protected void setBalance(double balance) {
        this.balance = balance;
    }
}

Kalıtım ve Çok Biçimlilik

Alt sınıflar temel sınıfları genişletir ve arayüzleri uygular:

public class SavingsAccount extends Account implements Transactable {
    private double interestRate;
    
    @Override
    public String getAccountType() {
        return "Savings";
    }
    
    public void applyInterest() {
        setBalance(getBalance() * (1 + interestRate));
    }
}

Kompozisyon

Sınıflar diğer nesnelerin koleksiyonlarını yönetebilir:

public class Bank {
    private ArrayList<Account> accounts;
    
    public void addAccount(Account account) {
        accounts.add(account);
    }
    
    public Account findAccount(String accountNumber) {
        // Hesabı ara ve döndür ya da null döndür
    }
}

Kapsülleme

Hassas verileri özel (private) alanlarla ve getter/setter'lar aracılığıyla kontrollü erişimle koruyun. Kapsüllemeyi korurken alt sınıf erişimine izin vermek için protected değiştiricilerini kullanın.

İşlemlerde İstisna Yönetimi

Geçersiz işlemler için özel istisnalar fırlatın:

public String transfer(String from, String to, double amount) throws InsufficientFundsException {
    if (!fromAccount.withdraw(amount)) {
        throw new InsufficientFundsException(amount, fromAccount.getBalance());
    }
    toAccount.deposit(amount);
    return "Transferred $" + amount;
}

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Bir Bank örneği oluşturun
        
        // TODO: Komutları tek tek almak için girişi virgüle göre ayırın
        
        // TODO: Her komutu işleyin:
        // - SAVINGS:accountNumber:balance:interestRate -> SavingsAccount oluşturun, "Account created: [accountNumber]" yazdırın
        // - CHECKING:accountNumber:balance:overdraftLimit -> CheckingAccount oluşturun, "Account created: [accountNumber]" yazdırın
        // - DEPOSIT:accountNumber:amount -> Para yatırın ve "Deposited $[amount] to [accountNumber]" yazdırın
        // - WITHDRAW:accountNumber:amount -> Para çekin ve başarılıysa yazdırın veya "Withdrawal failed: [accountNumber]" yazdırın
        // - TRANSFER:fromAccount:toAccount:amount -> Transfer yapın ve başarılıysa yazdırın veya "Transfer failed: [exception message]" yazdırın
        // - INTEREST:accountNumber -> Faizi uygulayın ve "Interest applied to [accountNumber]" yazdırın
        
        // TODO: Tüm komutlardan sonra "--- Bank Summary ---" yazdırın
        
        // TODO: getDetails() kullanarak her hesabın ayrıntılarını yazdırın
        
        // TODO: "Total deposits: $[total]" ifadesini virgülden sonra 2 basamak olacak şekilde yazdırın
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler