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
1 change: 1 addition & 0 deletions assignment
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

20 changes: 12 additions & 8 deletions src/Lecture4_interfaces_abstract_classes/BankAccount.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package Lecture4_interfaces_abstract_classes;

public class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(double balance) {
this.balance = balance;

public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}

public double getBalance() {
return balance;
public String getAccountNumber() { return accountNumber; }
public double getBalance() { return balance; }

public void deposit(double amount) {
this.balance += amount;
}

public void setBalance(double balance) {
this.balance = balance;
public void withdraw(double amount) {
this.balance -= amount;
}
}
67 changes: 27 additions & 40 deletions src/Lecture4_interfaces_abstract_classes/BaseTransaction.java
Original file line number Diff line number Diff line change
@@ -1,51 +1,38 @@
package Lecture4_interfaces_abstract_classes;

import org.jetbrains.annotations.NotNull;

import java.util.Calendar;
import java.util.UUID;

public abstract class BaseTransaction implements TransactionInterface {
private final int amount;
private final Calendar date;
private final String transactionID;
public class BaseTransaction implements TransactionInterface {
protected double amount;
protected Calendar date;
protected 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(double amount) {
this.amount = amount;
this.date = (Calendar) date.clone();
int uniq = (int) Math.random()*10000;
transactionID = date.toString()+uniq;
this.date = Calendar.getInstance();
this.transactionID = UUID.randomUUID().toString().substring(0, 8); // Unique short ID
}

/**
* getAmount()
* @return integer
*/
public double getAmount() {
return amount; // Because we are dealing with Value types we need not worry about what we return
}
@Override
public double getAmount() { return this.amount; }

@Override
public Calendar getDate() { return this.date; }

@Override
public String getTransactionID() { return this.transactionID; }

/**
* 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
@Override
public void printTransactionDetails() {
System.out.println("--- Transaction Details ---");
System.out.println("ID: " + transactionID);
System.out.println("Date: " + date.getTime());
System.out.println("Base Amount: KSh " + amount);
}

// Method to get a unique identifier for the transaction
public String getTransactionID(){
return transactionID;
// Question 1: Base implementation differs substantially from subclasses
@Override
public void apply(BankAccount ba) throws InsufficientFundsException {
System.out.println("[BaseTransaction] Checking system connectivity for account: " + ba.getAccountNumber());
System.out.println("[BaseTransaction] No balance modifications done by the base layer abstraction.");
}
// Method to print a transaction receipt or details
public abstract void printTransactionDetails();
public abstract void apply(BankAccount ba);
}
36 changes: 13 additions & 23 deletions src/Lecture4_interfaces_abstract_classes/DepositTrasaction.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,20 @@
package Lecture4_interfaces_abstract_classes;
public class DepositTransaction extends BaseTransaction {

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;
}
public DepositTransaction(double amount) {
super(amount);
}

// Method to print a transaction receipt or details
public void printTransactionDetails(){
System.out.println("Deposit Trasaction: "+this.toString());
// Question 1: Method Overriding
@Override
public void apply(BankAccount ba) {
ba.deposit(this.amount);
System.out.println("[Deposit] KSh " + amount + " successfully credited to Account " + ba.getAccountNumber());
}

public void apply(BankAccount ba){
double curr_balance = ba.getBalance();
double new_balance = curr_balance + getAmount();
ba.setBalance(new_balance);
@Override
public void printTransactionDetails() {
super.printTransactionDetails();
System.out.println("Type: DEPOSIT (Irreversible)");
System.out.println("---------------------------");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Question 3: Custom Exception extending Exception class
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}
16 changes: 2 additions & 14 deletions src/Lecture4_interfaces_abstract_classes/TransactionInterface.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
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 printTransactionDetails();
void apply(BankAccount ba) throws InsufficientFundsException;
}


97 changes: 65 additions & 32 deletions src/Lecture4_interfaces_abstract_classes/WithdrawalTransaction.java
Original file line number Diff line number Diff line change
@@ -1,45 +1,78 @@
package Lecture4_interfaces_abstract_classes;

import org.jetbrains.annotations.NotNull;

import java.util.Calendar;

public class WithdrawalTransaction extends BaseTransaction {
public WithdrawalTransaction(int amount, @NotNull Calendar date) {
super(amount, date);
private boolean isReversed = false;
private BankAccount associatedAccount;
private double shortFallAmount = 0.0; // Tracks partial failure record

public WithdrawalTransaction(double amount) {
super(amount);
}

private boolean checkDepositAmount(int amt) {
if (amt < 0) {
return false;
} else {
return true;
// Question 1 & 3: Overriding and using the 'throws' keyword
@Override
public void apply(BankAccount ba) throws InsufficientFundsException {
this.associatedAccount = ba; // Cache reference for potential reversal
if (ba.getBalance() < this.amount) {
throw new InsufficientFundsException("Error: Insufficient funds to complete transaction of KSh " + this.amount);
}
ba.withdraw(this.amount);
System.out.println("[Withdrawal] KSh " + amount + " successfully deducted from Account " + ba.getAccountNumber());
}

// Method to reverse the transaction
public boolean reverse() {
return true;
} // return true if reversal was successful
// Question 3: Overloaded apply() handling partial withdrawal using try-catch-finally
public void apply(BankAccount ba, boolean allowPartial) {
this.associatedAccount = ba;
if (!allowPartial) {
try {
apply(ba);
} catch (InsufficientFundsException e) {
System.out.println("[Handled Exception] " + e.getMessage());
}
return;
}

// Method to print a transaction receipt or details
public void printTransactionDetails() {
System.out.println("Deposit Trasaction: " + this.toString());
// Partial withdrawal logic: 0 < balance < withdrawal amount
try {
if (ba.getBalance() <= 0) {
throw new InsufficientFundsException("Account empty. Cannot perform partial withdrawal.");
} else if (ba.getBalance() < this.amount) {
double availableBalance = ba.getBalance();
this.shortFallAmount = this.amount - availableBalance;

ba.withdraw(availableBalance); // Clear the account balance
System.out.println("[Partial Withdrawal] Only KSh " + availableBalance + " could be withdrawn.");
} else {
apply(ba); // Enough money exists normally
}
} catch (InsufficientFundsException e) {
System.out.println("[Try-Catch Block Alert] " + e.getMessage());
} finally {
System.out.println("[Finally Block Executed] Record updated. Shortfall unfulfilled amount: KSh " + shortFallAmount);
}
}

/*
Oportunity for assignment: implementing different form of withdrawal
*/
public void apply(BankAccount ba) {
double curr_balance = ba.getBalance();
if (curr_balance > getAmount()) {
double new_balance = curr_balance - getAmount();
ba.setBalance(new_balance);
// Question 2: Reversal logic for withdrawals
public boolean reverse() {
if (isReversed) {
System.out.println("Transaction already reversed.");
return false;
}
if (associatedAccount != null) {
double amountToRestore = this.amount - this.shortFallAmount;
associatedAccount.deposit(amountToRestore);
this.isReversed = true;
System.out.println("[REVERSAL SUCCESS] Restored KSh " + amountToRestore + " to Account " + associatedAccount.getAccountNumber());
return true;
}
System.out.println("[REVERSAL FAILED] No associated bank account found.");
return false;
}

/*
Assignment 1 Q3: Write the Reverse method - a method unique to the WithdrawalTransaction Class
*/
@Override
public void printTransactionDetails() {
super.printTransactionDetails();
System.out.println("Type: WITHDRAWAL");
System.out.println("Status: " + (isReversed ? "REVERSED" : "ACTIVE"));
System.out.println("Shortfall Record: KSh " + shortFallAmount);
System.out.println("---------------------------");
}
}

Loading