Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/Lecture4_interfaces_abstract_classes/BaseTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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
*/
Expand Down
153 changes: 147 additions & 6 deletions src/Main.java
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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()
}
}