From 8c7fee02dc4b45c09d0f397943e608c8760af951 Mon Sep 17 00:00:00 2001 From: Mike Date: Wed, 20 May 2026 05:24:42 +0300 Subject: [PATCH 1/3] Completed Assignment one --- .../BaseTransaction.java | 17 +- .../DepositTrasaction.java | 2 + .../InsufficientFundsException.java | 22 +++ .../WithdrawalTransaction.java | 63 +++++++- src/Main.java | 153 +++++++++++++++++- 5 files changed, 243 insertions(+), 14 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..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 From ed1204f419fbfc35c6b211a06dff069dd2607f14 Mon Sep 17 00:00:00 2001 From: Franklin Thuku Date: Mon, 15 Jun 2026 23:34:01 +0300 Subject: [PATCH 2/3] Completed assignment --- .idea/IntelliLang.xml | 151 ++++++++++++++ .../BankAccount.java | 4 +- .../BaseTransaction.java | 59 ++---- .../DepositTrasaction.java | 20 +- .../InsufficientFundsException.java | 14 +- .../TransactionInterface.java | 13 +- .../WithdrawalTransaction.java | 110 +++++----- .../~$signment_I_Advanced_Programming.pdf | Bin 0 -> 162 bytes src/Main.java | 189 +++++------------- 9 files changed, 304 insertions(+), 256 deletions(-) create mode 100644 .idea/IntelliLang.xml create mode 100644 src/Lecture4_interfaces_abstract_classes/~$signment_I_Advanced_Programming.pdf diff --git a/.idea/IntelliLang.xml b/.idea/IntelliLang.xml new file mode 100644 index 0000000..b223a1b --- /dev/null +++ b/.idea/IntelliLang.xml @@ -0,0 +1,151 @@ + + + + + AsyncQueryRunner (org.apache.commons.dbutils) + + + + + + + + + + + + + + + + + + Jodd (jodd.db) + + + + + + + + MyBatis @Select/@Delete/@Insert/@Update + + + + + + + + QueryRunner (org.apache.commons.dbutils) + + + + + + + + + + + + + + + + + + R2DBC (io.r2dbc) + + + + + + Reactiverse Postgres Client (io.reactiverse) + + + + + + + + + + + + + SmallRye Axle SqlClient (io.vertx.axle.sqlclient) + + + + + + SmallRye Mutiny SqlClient (io.vertx.mutiny.sqlclient) + + + + + + SmallRye Mutiny SqlConnection (io.vertx.mutiny.sqlclient) + + + + + + + + Vert.x SQL Extensions (io.vertx.ext.sql) + + + + + + + Vert.x SQL Reactive Extensions (io.vertx.reactivex.ext.sql) + + + + + + + + + + Vert.x SqlClient (io.vertx.sqlclient) + + + + + + + + + + + Vert.x SqlClient RxJava2 (io.vertx.reactivex.sqlclient) + + + + + + + + + + + + jOOQ (org.jooq.DSLContext) + + + + + + + + rxjava2-jdbc (org.davidmoten.rx.jdbc) + + + + + + + \ No newline at end of file diff --git a/src/Lecture4_interfaces_abstract_classes/BankAccount.java b/src/Lecture4_interfaces_abstract_classes/BankAccount.java index 28d0d07..c935271 100644 --- a/src/Lecture4_interfaces_abstract_classes/BankAccount.java +++ b/src/Lecture4_interfaces_abstract_classes/BankAccount.java @@ -1,7 +1,9 @@ package Lecture4_interfaces_abstract_classes; public class BankAccount { + private double balance; + public BankAccount(double balance) { this.balance = balance; } @@ -13,4 +15,4 @@ public double getBalance() { public void setBalance(double balance) { this.balance = balance; } -} +} \ No newline at end of file diff --git a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java index efd6760..0602c16 100644 --- a/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java +++ b/src/Lecture4_interfaces_abstract_classes/BaseTransaction.java @@ -1,60 +1,45 @@ package Lecture4_interfaces_abstract_classes; -import org.jetbrains.annotations.NotNull; - import java.util.Calendar; -public class BaseTransaction implements TransactionInterface { +public abstract class BaseTransaction implements TransactionInterface { + private final int amount; 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) { + public BaseTransaction(int amount, 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); + this.transactionID = date.getTimeInMillis() + "-" + uniq; } - /** - * getAmount() - * @return integer - */ + @Override 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 - */ + @Override 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; + @Override + public String getTransactionID() { + return transactionID; } - // Concrete method to print a transaction receipt or details + + @Override 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); + System.out.println("--- Transaction Details ---"); + System.out.println("Transaction ID: " + transactionID); + System.out.println("Date: " + date.getTime()); + System.out.println("Amount: " + amount); } - // Concrete apply method — subclasses will override this + @Override public void apply(BankAccount ba) throws InsufficientFundsException { - System.out.println("Base apply() — no specific transaction action taken."); -} -} + System.out.println("Base transaction executed."); + } +} \ 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 af05fa1..f8c0442 100644 --- a/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java +++ b/src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java @@ -1,32 +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; + return false; } else{ - return true; + return true; } } - // Method to print a transaction receipt or details - @override + @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()); } + // Added 'throws InsufficientFundsException' to maintain signature compatibility @Override - public void apply(BankAccount ba){ + 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 index d0d3668..cf48eef 100644 --- a/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java +++ b/src/Lecture4_interfaces_abstract_classes/InsufficientFundsException.java @@ -1,21 +1,19 @@ 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 InsufficientFundsException(String message) { + super(message); + this.deficitAmount = 0.0; + } + public double getDeficitAmount() { return deficitAmount; } diff --git a/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java b/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java index 5902713..7bdeaf0 100644 --- a/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java +++ b/src/Lecture4_interfaces_abstract_classes/TransactionInterface.java @@ -1,21 +1,16 @@ package Lecture4_interfaces_abstract_classes; + import java.util.Calendar; -/** - * Interface for Transactions - * Any class that defines a transaction is expected to implement this Interface - */ public interface TransactionInterface { - // Method to get the transaction amount double getAmount(); - // Method to get the transaction date Calendar getDate(); - // Method to get a unique identifier for the transaction String getTransactionID(); -} - + void apply(BankAccount ba) throws InsufficientFundsException; + void printTransactionDetails(); +} \ 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 40190c5..7406cba 100644 --- a/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java +++ b/src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java @@ -1,12 +1,13 @@ package Lecture4_interfaces_abstract_classes; import org.jetbrains.annotations.NotNull; - import java.util.Calendar; public class WithdrawalTransaction extends BaseTransaction { - private boolean applied = false; - private boolean reversed = false; + private BankAccount appliedAccount = null; + private boolean isApplied = false; + private double shortfallRecord = 0.0; + public WithdrawalTransaction(int amount, @NotNull Calendar date) { super(amount, date); } @@ -19,82 +20,73 @@ private boolean checkDepositAmount(int amt) { } } - // Method to reverse the transaction - 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; + // Question 2: Reversal logic restores the account balance to its original amount + public boolean reverse() { + 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; } - } // return true if reversal was successful + 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("Withdrawal Transaction: " + this.toString()); - System.out.println(" Applied: " + applied); - System.out.println(" Reversed: " + reversed); - if (amountNotWithdrawn > 0) { - System.out.println(" Amount not withdrawn: " + amountNotWithdrawn); + 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 - */ - @Override + // 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()) { double new_balance = curr_balance - getAmount(); ba.setBalance(new_balance); - applied = true; - System.out.println("Withdrawal of " + getAmount() + " applied. New balance: " + new_balance); + this.appliedAccount = ba; + this.isApplied = true; + this.shortfallRecord = 0.0; } else { - double deficit = getAmount() - curr_balance; - throw new InsufficientFundsException( - "Insufficient funds! Balance: " + curr_balance + ", needed: " + getAmount(), deficit); + throw new InsufficientFundsException("Insufficient funds to complete the withdrawal of " + getAmount()); } } - public void apply(BankAccount ba, boolean withdrawAvailable) { - double curr_balance = ba.getBalance(); - + // Question 3: Overloaded apply handling 0 < balance < withdrawal amount using try...catch...finally + public void apply(BankAccount ba, boolean partialWithdrawalAllowed) { 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); + 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 { - System.out.println("No withdrawal made. Balance is 0."); + // 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("Withdrawal attempt completed"); + System.out.println("Transaction processing attempt finished for Transaction ID: " + getTransactionID()); } } - - public double getAmountNotWithdrawn() { - return amountNotWithdrawn; - } - /* - Assignment 1 Q3: Write the Reverse method - a method unique to the WithdrawalTransaction Class - */ -} - +} \ No newline at end of file diff --git a/src/Lecture4_interfaces_abstract_classes/~$signment_I_Advanced_Programming.pdf b/src/Lecture4_interfaces_abstract_classes/~$signment_I_Advanced_Programming.pdf new file mode 100644 index 0000000000000000000000000000000000000000..176fedd291ba253e81e99de94dbac03562c1ed36 GIT binary patch literal 162 zcmZQ|Ov%m6V;~W*GB`4%Fyu01GC;H%Jg(NC$;7~r&}Opw0?;fNy?QGnipfAFU;q<0 mYOp=>=g%F+B}aVKj(uZbX#0M54%6Q|j0LkG=Ikw4(FOohg&-&Z literal 0 HcmV?d00001 diff --git a/src/Main.java b/src/Main.java index 56d3ecf..9d3b022 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,5 +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 Lecture4_interfaces_abstract_classes.*; // Import Lecture 4 assignment files import java.util.Calendar; import java.util.GregorianCalendar; @@ -9,7 +9,7 @@ //TIP To Run code, press or // click the icon in the gutter. /* -* Client Code for accessing the Lecture1_adt.TransactionInterface.java module + * Client Code for accessing the Lecture1_adt.TransactionInterface.java module */ public class Main { @@ -57,8 +57,8 @@ 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 */ } @@ -144,154 +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 } - 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()); - } + /** + * Question 4: Client Code to test Assignment 1 functionality + */ + public static void testAssignmentOne() { + System.out.println("========== RUNNING ASSIGNMENT 1 TEST CODE =========="); - System.out.println("Balance after withdrawal: " + ba.getBalance()); - } + // 1. Setup account and common date object + BankAccount account = new BankAccount(5000.0); + Calendar now = new GregorianCalendar(); - public static void testWithdrawalException() { - System.out.println("\nTEST: Insufficient Funds Exception"); + System.out.println("Initial Bank Account Balance: " + account.getBalance()); - BankAccount ba = new BankAccount(100); - Calendar date = new GregorianCalendar(); - WithdrawalTransaction withdrawal = new WithdrawalTransaction(500, date); + // 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 - System.out.println("Balance: " + ba.getBalance()); - System.out.println("Attempting to withdraw: " + withdrawal.getAmount()); + // 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 { - 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()); + // 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 - 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("Successfully caught handled exception: " + 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(); + // 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()); - DepositTrasaction deposit = new DepositTrasaction(200, date); - WithdrawalTransaction withdrawal = new WithdrawalTransaction(300, date); + // 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()); - 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(); - } + System.out.println("===================================================="); } - public static void main(String[] args) { - // ===== OLD TESTS (from Lecture1_adt) ===== + // Run assignment test execution + testAssignmentOne(); + + // Uncomment the following lines to run historical lecture tests if needed // testTransaction1(); // testTransaction2(); // testTransaction3(); // testTransaction4(); - - // ===== NEW TESTS (Assignment 1) ===== - testDeposit(); - testWithdrawalSuccess(); - testWithdrawalException(); - testWithdrawalAvailableBalance(); - testReverse(); - testPolymorphism(); - } } \ No newline at end of file From 05f346fb7dc7516618f224998df53adff25ff2fc Mon Sep 17 00:00:00 2001 From: Franklin Thuku Date: Mon, 15 Jun 2026 23:34:38 +0300 Subject: [PATCH 3/3] Remove temporary file --- .../~$signment_I_Advanced_Programming.pdf | Bin 162 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/Lecture4_interfaces_abstract_classes/~$signment_I_Advanced_Programming.pdf diff --git a/src/Lecture4_interfaces_abstract_classes/~$signment_I_Advanced_Programming.pdf b/src/Lecture4_interfaces_abstract_classes/~$signment_I_Advanced_Programming.pdf deleted file mode 100644 index 176fedd291ba253e81e99de94dbac03562c1ed36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmZQ|Ov%m6V;~W*GB`4%Fyu01GC;H%Jg(NC$;7~r&}Opw0?;fNy?QGnipfAFU;q<0 mYOp=>=g%F+B}aVKj(uZbX#0M54%6Q|j0LkG=Ikw4(FOohg&-&Z