I created a simple bank program. The program asks for the user’s name and a starting balance. From there, the user can do 4 things, Check Balance, Add Funds, Transfer Funds and Exit the program. Check Balance simply returns the name of the user along with the remaining amount of funds in his account. Add Funds asks the user for an amount to put in his account. Transfer Funds asks the user for an amount to reduce from his account. This is a simple program that practices your understanding of objects and how to manipulate their fields. You can try Overriding a method to simplify one function of this program.
I posted this code in the hopes of getting people's opinion on if my program follows the standards of OOP and also for any improvements to how it is written. I am self-learning Java and would love any feedback so that I can learn from creating this program.
import java.util.Scanner;
public class Main {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
boolean quit = false;
int choice;
String accountName;
double startBalance;
System.out.printf("%24s\n","BankApp v1.0");
System.out.println("=====================================");
System.out.println("Please enter your details below.");
System.out.println("Account Name: ");
accountName = scanner.nextLine();
System.out.println("Starting Balance: ");
startBalance = scanner.nextDouble();
Account account = new Account(accountName,startBalance);
while(!quit){
printMainMenu();
choice = scanner.nextInt();
switch(choice){
case 1:
System.out.printf("Account Name: %s\nAccount Balance: $%.2f\n",account.getAccountName(),
account.getAccountBal());
break;
case 2:
System.out.println("Enter amount to be added: ");
account.addFunds(scanner.nextDouble());
break;
case 3:
System.out.println("Enter amount to be transferred: ");
account.transferFunds(scanner.nextDouble());
break;
case 4:
quit = true;
break;
default:
System.out.println("Invalid choice.");
break;
}
}
scanner.close();
}
public static void printMainMenu(){
System.out.printf("%24s\n" +
"=====================================\n" +
"Please select an option:\n" +
"1 - Check Balance\n" +
"2 - Add Funds\n" +
"3 - Transfer Funds\n" +
"4 - Exit the program\n" +
"=====================================\n" +
"Choice: ","BankApp v1.0");
}
}
This is the Account class code.
public class Account {
private String accountName;
private double accountBal;
public Account(String accountName, double accountBal) {
if(accountBal < 0) {
System.out.println("Starting balance cannot be less than zero.\nBalance set to 0ドル.00");
}else {
this.accountName = accountName;
this.accountBal = accountBal;
System.out.println("Account initialized.\nBalance set to $" + this.accountBal);
}
}
public String getAccountName() {
return accountName;
}
public double getAccountBal() {
return accountBal;
}
public void transferFunds(double withdrawal){
if(withdrawal > this.accountBal){
System.out.printf("Unable to transfer $%.2f. Balance is insufficient.\n",withdrawal);
}else if(withdrawal < 0){
System.out.println("Transfer amount must be greater than zero. Transfer failed.");
}else{
this.accountBal -= withdrawal;
System.out.printf("Transfer of $%.2f successful. Your new balance is $%.2f.\n",withdrawal,this.accountBal);
}
}
public void addFunds(double deposit){
if(deposit < 0){
System.out.println("Amount deposited must be greater than zero.");
}else {
this.accountBal += deposit;
System.out.printf("Deposit of $%.2f successful. Your new balance is $%.2f.\n",deposit,this.accountBal);
}
}
}
2 Answers 2
Naming
- Even though this is only an example application you should use proper names
public class Main
could have a far better name, maybe think ofpublic class ExerciseObjectManipulation
. You can find such classes later much easier in your SCM - Avoid redundancy in your variables, for example
Account.accountName
andAccount.accountBal
. That gives you the chance for proper naming ofAccount.accountBal
intoAccount.balance
(also: avoid abbreviations in namings) - same applies for these method names
getAccountName
andgetAccountBal
Seperation of concerns
- your main method is responisble for printing, inputhandling and program flow - maybe you could use separate methods (or even: separate objects) for these responsibilities? Did you realize that you already started doing that by creating a methode
printMainMenu()
i'm sure you could find some more responsibilities for aclass Printer
?!! - provide a Constructor for
Account
without balancepublic Account(String name, double balance) { this(name,0);}
to create Accounts without balance.
error handling
- it's nice that you write your concerns into the
System.out
(even if it would be more approperiate to write toSystem.error
- but the proper way to do it would be to throw anException
! right now it is possible to create anAccount
with negative balance even if then not all attributes are set - this is terrible, you create an unfinished object!
.
public Account(String name, double balance) {
if(accountBal < 0) {
throw new IllegalArgumentException("Starting balance cannot be less than zero");
}
this.name = name;
this.balance = balance;
}
- use this approach for any invalid parameters you get, see
transferFunds()
, seeaddFunds()
logic flaws
if(deposit < 0){
System.out.println("Amount deposited must be greater than zero.");
}
either deposit <= 0
or cannot be less than zero.
same here: if(withdrawal < 0)
One advice I can give is to throw exceptions or return true/false from methods in Account
class to that the client (in your case main class) could take the necessary action. The problem I see here is the Account
class prints some texts that are displayed to user. Obviously, this is not Account
class' job.
Secondly, there are too many lines of code in your main method which makes me think that you should create a class/methods and distribute the work accordingly at first glance.