From dd0c293441746f7a5b30348d1d6cbbb761acdafe Mon Sep 17 00:00:00 2001 From: rastogras <104068108+ROYKIP103@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:20:52 +0300 Subject: [PATCH] SCT212-0451/2024 OOP 2 assignment complete --- .../BaseTransaction.java | 46 ++++------- .../DepositTrasaction.java | 18 ++-- .../InsufficientFundsException.java | 7 ++ .../WithdrawalTransaction.java | 77 +++++++++++++---- src/Main.java | 82 ++++++++++++++++--- 5 files changed, 171 insertions(+), 59 deletions(-) create mode 100644 src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java diff --git a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java index ed81eb8..8ed583e 100644 --- a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java +++ b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java @@ -1,7 +1,6 @@ package Lecture4_interfaces_abstract_classes; import org.jetbrains.annotations.NotNull; - import java.util.Calendar; public abstract class BaseTransaction implements TransactionInterface { @@ -9,43 +8,34 @@ public abstract class BaseTransaction implements TransactionInterface { private final Calendar date; private final String transactionID; - /** - * Lecture1_adt.TransactionInterface Constructor - * @param amount in an integer - * @param date: Not null, and must be a Calendar object - * @return void - * Instialises the field, attributes of a transaction - * Creates a object of this - */ public BaseTransaction(int amount, @NotNull Calendar date) { this.amount = amount; this.date = (Calendar) date.clone(); - int uniq = (int) Math.random()*10000; - transactionID = date.toString()+uniq; + int uniq = (int) (Math.random() * 10000); + transactionID = date.toString() + uniq; } - /** - * getAmount() - * @return integer - */ public double getAmount() { - return amount; // Because we are dealing with Value types we need not worry about what we return + return amount; } - /** - * getDate() - * @return Calendar Object - */ public Calendar getDate() { -// return date; // Because we are dealing with Reference types we need to judiciously copy what our getters return - return (Calendar) date.clone(); // Defensive copying or Judicious Copying + return (Calendar) date.clone(); } - // Method to get a unique identifier for the transaction public String getTransactionID(){ - return transactionID; + return transactionID; + } + + public void printTransactionDetails() { + System.out.println("--- Transaction Details ---"); + System.out.println("Transaction ID: " + getTransactionID()); + System.out.println("Date: " + getDate().getTime()); + System.out.println("Amount: " + getAmount()); + } + + // Added 'throws InsufficientFundsException' so subclasses can throw it + public void apply(BankAccount ba) throws InsufficientFundsException { + System.out.println("Base transaction of " + getAmount() + " processed on account. No balance changes made."); } - // Method to print a transaction receipt or details - public abstract void printTransactionDetails(); - public abstract void apply(BankAccount ba); -} +} \ No newline at end of file diff --git a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java index 81afab5..fe222c4 100644 --- a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java +++ b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java @@ -1,30 +1,36 @@ package Lecture4_interfaces_abstract_classes; import org.jetbrains.annotations.NotNull; - import java.util.Calendar; public class DepositTrasaction extends BaseTransaction { + public DepositTrasaction(int amount, @NotNull Calendar date){ super(amount, date); } + private boolean checkDepositAmount(int amt){ if (amt < 0){ return false; } else{ - return true; + return true; } } - // Method to print a transaction receipt or details + @Override public void printTransactionDetails(){ - System.out.println("Deposit Trasaction: "+this.toString()); + System.out.println("--- Deposit Transaction ---"); + System.out.println("Transaction ID: " + getTransactionID()); + System.out.println("Date: " + getDate().getTime()); + System.out.println("Amount Deposited: " + getAmount()); } - public void apply(BankAccount ba){ + // Added 'throws InsufficientFundsException' to maintain signature compatibility + @Override + public void apply(BankAccount ba) throws InsufficientFundsException { double curr_balance = ba.getBalance(); double new_balance = curr_balance + getAmount(); ba.setBalance(new_balance); } -} +} \ No newline at end of file diff --git a/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java new file mode 100644 index 0000000..1d96b37 --- /dev/null +++ b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java @@ -0,0 +1,7 @@ +package Lecture4_interfaces_abstract_classes; + +public class InsufficientFundsException extends Exception { + public InsufficientFundsException(String message) { + super(message); + } +} \ 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..7406cba 100644 --- a/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java +++ b/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java @@ -1,10 +1,13 @@ package Lecture4_interfaces_abstract_classes; import org.jetbrains.annotations.NotNull; - import java.util.Calendar; public class WithdrawalTransaction extends BaseTransaction { + private BankAccount appliedAccount = null; + private boolean isApplied = false; + private double shortfallRecord = 0.0; + public WithdrawalTransaction(int amount, @NotNull Calendar date) { super(amount, date); } @@ -17,29 +20,73 @@ private boolean checkDepositAmount(int amt) { } } - // Method to reverse the transaction + // Question 2: Reversal logic restores the account balance to its original amount public boolean reverse() { - return true; - } // return true if reversal was successful + if (isApplied && appliedAccount != null) { + double currentBalance = appliedAccount.getBalance(); + // Restore original amount (current balance + what was successfully withdrawn) + double restoredBalance = currentBalance + (getAmount() - shortfallRecord); + appliedAccount.setBalance(restoredBalance); + isApplied = false; // Reset state + System.out.println("Withdrawal transaction reversed successfully."); + return true; + } + System.out.println("Reversal failed: Transaction has not been applied yet."); + return false; + } // Method to print a transaction receipt or details + @Override public void printTransactionDetails() { - System.out.println("Deposit Trasaction: " + this.toString()); + System.out.println("--- Withdrawal Transaction ---"); + System.out.println("Transaction ID: " + getTransactionID()); + System.out.println("Date: " + getDate().getTime()); + System.out.println("Amount Requested: " + getAmount()); + if (shortfallRecord > 0) { + System.out.println("Shortfall (Not Withdrawn): " + shortfallRecord); + } } - /* - Oportunity for assignment: implementing different form of withdrawal - */ - public void apply(BankAccount ba) { + // Question 3: Standard apply using the throws keyword + @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); + this.appliedAccount = ba; + this.isApplied = true; + this.shortfallRecord = 0.0; + } else { + throw new InsufficientFundsException("Insufficient funds to complete the withdrawal of " + getAmount()); } } - /* - Assignment 1 Q3: Write the Reverse method - a method unique to the WithdrawalTransaction Class - */ -} - + // Question 3: Overloaded apply handling 0 < balance < withdrawal amount using try...catch...finally + public void apply(BankAccount ba, boolean partialWithdrawalAllowed) { + try { + double curr_balance = ba.getBalance(); + if (curr_balance < getAmount()) { + // Check if balance is greater than 0 for partial withdrawal + if (curr_balance > 0) { + shortfallRecord = getAmount() - curr_balance; + ba.setBalance(0.0); // Withdraw all available balance + this.appliedAccount = ba; + this.isApplied = true; + System.out.println("Partial withdrawal executed. Balance set to 0. Shortfall: " + shortfallRecord); + } else { + // Trigger exception block manually if balance is 0 or less + throw new InsufficientFundsException("Account balance is zero or negative. Cannot withdraw."); + } + } else { + // If funds are completely sufficient, proceed normally via standard apply + apply(ba); + } + } catch (InsufficientFundsException e) { + System.out.println("Caught Exception inside overloaded apply: " + e.getMessage()); + this.isApplied = false; + } finally { + System.out.println("Transaction processing attempt finished for Transaction ID: " + getTransactionID()); + } + } +} \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 584a048..fc4e77f 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 Lecture 4 assignment files import java.util.Calendar; import java.util.GregorianCalendar; @@ -56,9 +57,9 @@ public static void testTransaction2() { System.out.println("Lecture1_adt.TransactionInterface Date: \t "+modified_t.getDate().getTime()); /* Please note that Although we have solved the problem of Transaction1 - * And client code can no longer use the dot (.) operator to directly access the data - * There is still some exposure especially if we pass an object of a previous Transaction2 to create a new Transaction2 object - */ + * And client code can no longer use the dot (.) operator to directly access the data + * There is still some exposure especially if we pass an object of a previous Transaction2 to create a new Transaction2 object + */ } @@ -143,14 +144,75 @@ public static void testTransaction4() { // Please Take a look at all the 12 transaction now and compare with the outputs of the Transaction3 class } + /** + * Question 4: Client Code to test Assignment 1 functionality + */ + public static void testAssignmentOne() { + System.out.println("========== RUNNING ASSIGNMENT 1 TEST CODE =========="); + + // 1. Setup account and common date object + BankAccount account = new BankAccount(5000.0); + Calendar now = new GregorianCalendar(); + + System.out.println("Initial Bank Account Balance: " + account.getBalance()); + + // 2. Instantiate Subclass Objects + DepositTrasaction deposit = new DepositTrasaction(2000, now); + WithdrawalTransaction withdrawal1 = new WithdrawalTransaction(3000, now); + WithdrawalTransaction withdrawal2 = new WithdrawalTransaction(6000, now); // Will cause exception + WithdrawalTransaction partialWithdrawal = new WithdrawalTransaction(8000, now); // For overloaded test + + // 3. Type casting / Mapping subtype objects to the base type object (Upcasting) + BaseTransaction baseDeposit = (BaseTransaction) deposit; + BaseTransaction baseWithdrawal1 = (BaseTransaction) withdrawal1; + BaseTransaction baseWithdrawal2 = (BaseTransaction) withdrawal2; + + try { + // 4. Apply Deposit via Base type mapping + System.out.println("\n--- Executing Deposit ---"); + baseDeposit.apply(account); + baseDeposit.printTransactionDetails(); + System.out.println("Balance after Deposit: " + account.getBalance()); + + // 5. Apply valid Withdrawal via Base type mapping + System.out.println("\n--- Executing Valid Withdrawal ---"); + baseWithdrawal1.apply(account); + baseWithdrawal1.printTransactionDetails(); + System.out.println("Balance after Withdrawal 1: " + account.getBalance()); + + // 6. Test Reversal on the successful withdrawal + System.out.println("\n--- Testing Reversal on Withdrawal 1 ---"); + withdrawal1.reverse(); + System.out.println("Balance after Reversal: " + account.getBalance()); + + // 7. Apply invalid Withdrawal (Should throw InsufficientFundsException) + System.out.println("\n--- Executing Invalid Withdrawal (Expect Exception) ---"); + baseWithdrawal2.apply(account); // This line will jump to the catch block + + } catch (InsufficientFundsException e) { + System.out.println("Successfully caught handled exception: " + e.getMessage()); + } + + // 8. Test Overloaded apply method (Partial withdrawal scenario) + System.out.println("\n--- Executing Overloaded Apply (Partial Withdrawal Option) ---"); + System.out.println("Current Account Balance before partial: " + account.getBalance()); + + // Attempting to withdraw 8000 when balance is less than that but greater than 0 + partialWithdrawal.apply(account, true); + partialWithdrawal.printTransactionDetails(); + System.out.println("Final Account Balance after partial withdrawal loop: " + account.getBalance()); + + System.out.println("===================================================="); + } 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 - - // testTransaction1() - // testTransaction2() - // testTransaction3() - // testTransaction4() + // Run assignment test execution + testAssignmentOne(); + + // Uncomment the following lines to run historical lecture tests if needed + // testTransaction1(); + // testTransaction2(); + // testTransaction3(); + // testTransaction4(); } } \ No newline at end of file