diff --git a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java index ed81eb8..efd6760 100644 --- a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java +++ b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java @@ -4,7 +4,7 @@ import java.util.Calendar; -public abstract class BaseTransaction implements TransactionInterface { +public class BaseTransaction implements TransactionInterface { private final int amount; private final Calendar date; private final String transactionID; @@ -45,7 +45,16 @@ public Calendar getDate() { public String getTransactionID(){ return transactionID; } - // Method to print a transaction receipt or details - public abstract void printTransactionDetails(); - public abstract void apply(BankAccount ba); + // Concrete method to print a transaction receipt or details + public void printTransactionDetails() { + System.out.println("Base Transaction Details:"); + System.out.println(" Amount: " + amount); + System.out.println(" Date: " + date.getTime()); + System.out.println(" Transaction ID: " + transactionID); + } + + // Concrete apply method — subclasses will override this + public void apply(BankAccount ba) throws InsufficientFundsException { + System.out.println("Base apply() — no specific transaction action taken."); +} } diff --git a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java index 81afab5..af05fa1 100644 --- a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java +++ b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java @@ -18,10 +18,12 @@ private boolean checkDepositAmount(int amt){ } // Method to print a transaction receipt or details + @override public void printTransactionDetails(){ System.out.println("Deposit Trasaction: "+this.toString()); } + @Override public void apply(BankAccount ba){ double curr_balance = ba.getBalance(); double new_balance = curr_balance + getAmount(); diff --git a/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java new file mode 100644 index 0000000..d0d3668 --- /dev/null +++ b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java @@ -0,0 +1,22 @@ +package Lecture4_interfaces_abstract_classes; +public class InsufficientFundsException extends Exception { + + private double deficitAmount; + + /** + * Constructor + * @param message Description of the error + * @param deficit The amount by which the balance falls short + */ + public InsufficientFundsException(String message, double deficit) { + super(message); + this.deficitAmount = deficit; + } + + /** + * @return The amount still needed to cover the withdrawal + */ + public double getDeficitAmount() { + return deficitAmount; + } +} \ No newline at end of file diff --git a/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java b/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java index face5b6..40190c5 100644 --- a/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java +++ b/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java @@ -5,6 +5,8 @@ import java.util.Calendar; public class WithdrawalTransaction extends BaseTransaction { + private boolean applied = false; + private boolean reversed = false; public WithdrawalTransaction(int amount, @NotNull Calendar date) { super(amount, date); } @@ -18,26 +20,79 @@ private boolean checkDepositAmount(int amt) { } // Method to reverse the transaction - public boolean reverse() { + public boolean reverse(BankAccount ba) { + if (applied && !reversed) { + double curr_balance = ba.getBalance(); + double new_balance = curr_balance + getAmount(); + ba.setBalance(new_balance); + reversed = true; + System.out.println("Withdrawal reversed. Amount returned: " + getAmount()); return true; + } + else if (reversed) { + System.out.println("Transaction has already been reversed."); + return false; + } else { + System.out.println("Transaction was never applied, cannot reverse."); + return false; + } } // return true if reversal was successful // Method to print a transaction receipt or details + @Override public void printTransactionDetails() { - System.out.println("Deposit Trasaction: " + this.toString()); + System.out.println("Withdrawal Transaction: " + this.toString()); + System.out.println(" Applied: " + applied); + System.out.println(" Reversed: " + reversed); + if (amountNotWithdrawn > 0) { + System.out.println(" Amount not withdrawn: " + amountNotWithdrawn); + } } /* Oportunity for assignment: implementing different form of withdrawal */ - public void apply(BankAccount ba) { + @Override + public void apply(BankAccount ba) throws InsufficientFundsException { double curr_balance = ba.getBalance(); - if (curr_balance > getAmount()) { + + if (curr_balance >= getAmount()) { double new_balance = curr_balance - getAmount(); ba.setBalance(new_balance); + applied = true; + System.out.println("Withdrawal of " + getAmount() + " applied. New balance: " + new_balance); + } else { + double deficit = getAmount() - curr_balance; + throw new InsufficientFundsException( + "Insufficient funds! Balance: " + curr_balance + ", needed: " + getAmount(), deficit); } } + public void apply(BankAccount ba, boolean withdrawAvailable) { + double curr_balance = ba.getBalance(); + + try { + apply(ba); + } catch (InsufficientFundsException e) { + System.out.println("Exception caught: " + e.getMessage()); + + if (curr_balance > 0 && withdrawAvailable) { + amountNotWithdrawn = getAmount() - curr_balance; + ba.setBalance(0); + applied = true; + System.out.println("Withdrew available balance: " + curr_balance); + System.out.println("Amount not withdrawn (shortfall): " + amountNotWithdrawn); + } else { + System.out.println("No withdrawal made. Balance is 0."); + } + } finally { + System.out.println("Withdrawal attempt completed"); + } + } + + public double getAmountNotWithdrawn() { + return amountNotWithdrawn; + } /* Assignment 1 Q3: Write the Reverse method - a method unique to the WithdrawalTransaction Class */ diff --git a/src/Main.java b/src/Main.java index 584a048..56d3ecf 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,4 +1,5 @@ import Lecture1_adt.*; // Import all classes from Lecture1_adt package to be used in this client code +import Lecture4_interfaces_abstract_classes.*; import java.util.Calendar; import java.util.GregorianCalendar; @@ -143,14 +144,154 @@ public static void testTransaction4() { // Please Take a look at all the 12 transaction now and compare with the outputs of the Transaction3 class } + public static void testDeposit() { + System.out.println("\nTEST: Deposit Transaction"); + + BankAccount ba = new BankAccount(1000); + Calendar date = new GregorianCalendar(); + DepositTrasaction deposit = new DepositTrasaction(500, date); + + System.out.println("Balance before deposit: " + ba.getBalance()); + deposit.printTransactionDetails(); + + try { + deposit.apply(ba); + } catch (InsufficientFundsException e) { + System.out.println("Deposits don't throw this."); + } + + System.out.println("Balance after deposit: " + ba.getBalance()); + } + + public static void testWithdrawalSuccess() { + System.out.println("\nTEST: Successful Withdrawal"); + + BankAccount ba = new BankAccount(1000); + Calendar date = new GregorianCalendar(); + WithdrawalTransaction withdrawal = new WithdrawalTransaction(300, date); + + System.out.println("Balance before withdrawal: " + ba.getBalance()); + withdrawal.printTransactionDetails(); + + try { + withdrawal.apply(ba); + } catch (InsufficientFundsException e) { + System.out.println("Should NOT happen: " + e.getMessage()); + } + + System.out.println("Balance after withdrawal: " + ba.getBalance()); + } + + public static void testWithdrawalException() { + System.out.println("\nTEST: Insufficient Funds Exception"); + + BankAccount ba = new BankAccount(100); + Calendar date = new GregorianCalendar(); + WithdrawalTransaction withdrawal = new WithdrawalTransaction(500, date); + + System.out.println("Balance: " + ba.getBalance()); + System.out.println("Attempting to withdraw: " + withdrawal.getAmount()); + + try { + withdrawal.apply(ba); + } catch (InsufficientFundsException e) { + System.out.println("Exception: " + e.getMessage()); + System.out.println("Deficit amount: " + e.getDeficitAmount()); + } + + System.out.println("Balance after failed attempt: " + ba.getBalance()); + } + + public static void testWithdrawalAvailableBalance() { + System.out.println("\nTEST: Overloaded apply() — Available Balance"); + + BankAccount ba = new BankAccount(150); + Calendar date = new GregorianCalendar(); + WithdrawalTransaction withdrawal = new WithdrawalTransaction(500, date); + + System.out.println("Balance: " + ba.getBalance()); + System.out.println("Attempting to withdraw: " + withdrawal.getAmount()); + + withdrawal.apply(ba, true); + + System.out.println("Balance after: " + ba.getBalance()); + System.out.println("Amount not withdrawn: " + withdrawal.getAmountNotWithdrawn()); + withdrawal.printTransactionDetails(); + } + + public static void testReverse() { + System.out.println("\nTEST: Reverse Withdrawal"); + + BankAccount ba = new BankAccount(1000); + Calendar date = new GregorianCalendar(); + WithdrawalTransaction withdrawal = new WithdrawalTransaction(400, date); + + System.out.println("Original balance: " + ba.getBalance()); + + try { + withdrawal.apply(ba); + } catch (InsufficientFundsException e) { + System.out.println("Should NOT happen: " + e.getMessage()); + } + + System.out.println("Balance after withdrawal: " + ba.getBalance()); + + boolean reversed = withdrawal.reverse(ba); + System.out.println("Reversed? " + reversed); + System.out.println("Balance after reversal: " + ba.getBalance()); + + boolean reversedAgain = withdrawal.reverse(ba); + System.out.println("Reversed again? " + reversedAgain); + } + + public static void testPolymorphism() { + System.out.println("\nTEST: Polymorphism"); + + BankAccount ba1 = new BankAccount(1000); + BankAccount ba2 = new BankAccount(500); + Calendar date = new GregorianCalendar(); + + DepositTrasaction deposit = new DepositTrasaction(200, date); + WithdrawalTransaction withdrawal = new WithdrawalTransaction(300, date); + + BaseTransaction bt1 = deposit; + BaseTransaction bt2 = withdrawal; + + System.out.println("\nApplying via BaseTransaction reference"); + + try { + bt1.apply(ba1); + System.out.println("After deposit (via base ref): " + ba1.getBalance()); + + bt2.apply(ba2); + System.out.println("After withdrawal (via base ref): " + ba2.getBalance()); + } catch (InsufficientFundsException e) { + System.out.println("Exception: " + e.getMessage()); + } + + System.out.println("\nDynamic Binding Demo"); + BaseTransaction[] transactions = {deposit, withdrawal}; + for (BaseTransaction bt : transactions) { + System.out.print("Transaction type: "); + bt.printTransactionDetails(); + } + } + public static void main(String[] args) { - // This is the client code - // Uncomment the following lines to test the class which you would like to test + // ===== OLD TESTS (from Lecture1_adt) ===== + // testTransaction1(); + // testTransaction2(); + // testTransaction3(); + // testTransaction4(); + + // ===== NEW TESTS (Assignment 1) ===== + testDeposit(); + testWithdrawalSuccess(); + testWithdrawalException(); + testWithdrawalAvailableBalance(); + testReverse(); + testPolymorphism(); - // testTransaction1() - // testTransaction2() - // testTransaction3() - // testTransaction4() } } \ No newline at end of file