How do I create objects using more than one constructor? - java

I wrote the following code and driver program but I am not sure how to create bank account objects using both constructors. One constructor takes an initial balance and the second constructor opens an account with no money. Also, should the accountBalance include validity checks?
Optionally, I could do the following:
Include a fee as part of what describes a bank account. Update the BankAccount class as necessary. The user should be able to set the fee amount for each account and add the fee through a method. Add code to the driver program to demonstrate the fee functionality. (Could someone explain to me what this is asking)
//Bank Account class
import java.text.NumberFormat;
public class BankAccount {
private String ownerName;
private String accountId;
private double accountBalance;
public BankAccount(String ownerName, String accountId, double accountBalance) {
this.ownerName = ownerName;
this.accountId = accountId;
if(accountBalance >= 0) {
this.accountBalance = accountBalance;
} else {
System.out.println("Due to your negative account balace, you will be issued a fee.\n");
}
}
public BankAccount(double accountBalance) {
accountBalance = 0;
}
public String getOwnerName() {
return ownerName;
}
public void setOwnerName(String ownerName) {
this.ownerName = ownerName;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(double accountBalance) {
if(accountBalance >= 0) {
this.accountBalance = accountBalance;
} else {
System.out.println("Due to your negative account balace, you will be issued a fee.\n");
}
}
public void withdraw(double amount) {
if(amount > 0 && amount < accountBalance) {
accountBalance -= amount;
} else {
System.out.println("Invalid withdraw amount! Please try again.\n");
}
}
public void deposit(double amount) {
if(amount > 0) {
accountBalance += amount;
} else {
System.out.println("Invalid deposit amount! Please try again.\n");
}
}
public String toString() {
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance();
return "Account Owner's Name: " + ownerName + "\n" + "Account ID: " + accountId + "\n" +
"Balance in the account: " + currencyFormatter.format(accountBalance);
}
}
//Driver Program
public class BankAccountDriver {
public static void main(String[] args) {
BankAccount myAccount = new BankAccount("Smith", "123jahgsd", 1200);
myAccount.withdraw(0.453);
myAccount.deposit(1000.1);
System.out.println(myAccount);
}
}

All nice answers, but they actually "miss" the "real" issue; and that is: you don't put down constructors because you can.
You create the code that is required to fulfill your requirements. In other words: you step back; and you think up respectively design the "intended use cases" for your bank account class.
And things to consider there: you avoid classes that can be created using such different paths.
Example: it is extremely dangerous to allow for empty id / owner fields. That leaves those fields with null values; and that means that you either need a lot of checking here and there; and if you forgot that here or there; you will run into NullPointerExceptions sooner or later (rather soon).
And keep in mind: your objects are meant to represent (model!) "reality". In reality, a bank account doesn't go without an owner; or an id.
In that sense, a sane implementation of your class would much more look like:
public class BankAccount {
private final String owner;
private final String id;
private double currentBalance;
public BankAccount(String owner, String id) {
this(ownwer, id, 0);
}
public BankAccount(String owner, String id, double currentBalance) {
this.owner = owner;
...
Notes here:
You want to prevent owner/id to be changed, so you make them final; and thus you also don't have setter methods for those fields
In a real world solution, you would not use Strings to represent names or ids, but distinct classes
You would also never ever use double to represent currency. This is a superbasic thing: money should not be represented using floating point numbers! (You would be looking towards to the BigDecimal class; or simply using int instead of double (and represent 1.75 $ as 175 cent)
And just a glance of real real world: nowadays, you don't model a bankaccount to have a "current balance". Instead, a bank account might be affiliated to a history of events (denoting deposits and pay-off transactions).
Final point: for your current exercise, that kind of "validation" for withdrawl/deposit is "okay"; in the "real world" validation would probably happen in many other places, too. (coming back to my initial statement: it all depends on your model; a simple model could say that a bank account itself is "validating" things; but a more realistic solution is that you have other components that deal with "rules", "laws" and all kinds of topics that do "validation").

You can do like this:
public BankAccount(String ownerName, String accountId, double accountBalance) {
this.ownerName = ownerName;
this.accountId = accountId;
this.accountBalance = accountBalance;
}
public BankAccount() {
this("some default name", "some default id", 0.0);
}

If you want to create a BankAccount with a zero balance then
public BankAccount(String ownerName, String accountId, double accountBalance) {
this.ownerName = ownerName;
this.accountId = accountId;
this.accountBalance = accountBalance;
}
public BankAccount() {
this.accountBalance = 0;
}
You can instantiate them as
BankAccount mine = new BankAccount("Scary", "123", 1000000.00);
BankAccount empty = new BankAccount();
edit
If you choose to construct a method with the second method, the id and owner would also be null and maybe not very useful

You can't create one bank account object using both constructors. You only call one of the two constructors to create a new object. So you either do:
BankAccount account = new BankAccount("Sweeper", "ABCDEF", 10000);
or:
BankAccount account = new BankAccount(100000);
Note that your second constructor's parameter is pointless because you initialize the balance to 0 no matter what the parameter is:
public BankAccount(double accountBalance) {
accountBalance = 0;
}
I think this makes more sense:
public BankAccount() {
this.accountBalance = 0;
}
As for your second question, I will give you some tips.
You need to add a new field to the class, called fee. Add getters and setters for it.

You make objects depending on which constructor you want to use. For example, to use the first constructor you need three parameters like so,
BankAccount first = new BankAccount("Bob", "ID45", 400.50);
and to use the second constructor you only need one parameter, the balance, like so,
BankAccount second = new BankAccount(400.50);
They'll both make instances of BankAccount except the difference is that on creation, the first bank account will have fields ownerName and accountId filled out while the second bank account will have those fields set to empty String values. However, the second object will have a balance of 0 unlike the first object's balance of 400.5
EDIT: Like user ScaryWombat suggested, there is a flaw in your second constructor because if you want to define an object with a balance of 0 then there's no point in adding a balance parameter. Also, in this case it would be advisable to give default values to your other fields as well,
public BankAccount() {
ownerName = "unknown";
accountId = "unknown";
accountBalance = 0;
}
So now when you create an instance of BankAccount with this constructor, it'll have the default values, "unknown", "unknown", and 0.
BankAccount third = new BankAccount();
Also, for the fee part, all you have to do is not only create another field in your BankAccount class called fee but also make a setter method to allow the user to set its fee,
private double fee;
.
.
.
public void setFee (double fee) {
this.fee = fee;
}
And in the main method, the user can access it with the following,
BankAccount account = new BankAccount("Fred", "ID145", 400);
account.setFee(15); //this will set the fee to 15

Related

How to add an object to array which is an instance variable of a class in java

I have two classes named Bank and BankAccount. There is a createBankAccount method in Bank in class. I want to create an object of Bank and then add it in the record array which is a instance variable of Bank class.
class BankAccount{
double balance;
int id;
// Type of the account. Can be of two types: current or savings
String accountType;
// i. Write a Constructor
public BankAccount(double balance, int id, String accountType) {
this.balance = balance;
this.id = id;
this.accountType = accountType;
}
// ii. This function increses the balance by amount
public void deposit(double amount){
balance += amount;
}
// iii. This function decreases the balance by amount
public void withdraw(double amount){
balance -= amount;
}
}
class Bank{
BankAccount records[];
double savingInterestRate = 3.5;
double currentInterestRate = 0.4;
// iv. Write a constructor
public Bank(BankAccount[] records, double savingInterestRate, double currentInterestRate) {
this.records = records;
this.savingInterestRate = savingInterestRate;
this.currentInterestRate = currentInterestRate;
}
// v. Complete the function
public void createBankAccount(double initialBalance, int accountId, String accountType){
//Create a object of BankAccount class
// Add the object to records array
BankAccount ac = new BankAccount(initialBalance, accountId, accountType);
}
}
How do I add the BankAccount object which is created in createBankAccount method to the records array??
Is there any specific requirement to use array for records? Can't you just use a list for the same and then you can add to and remove from the list as you wish.

Accessing account balance in Bank System application

I am currently trying to create a simple bank program in which users can create an account, deposit and withdraw money. The problem is that I am having trouble with creating accounts.
Here is my main:
Account account = new Account();
account.createAccount(1000, "Bob");
Here is my Account.java class:
public void createAccount(int bal, String name){
int balance = bal;
String username = name;
System.out.println("An account has been set up for "+name+", with a balance of $"+bal+".");
The problem I'm having is accessing the accounts which are created.
The account is created and the string runs, but I am not sure how I would be able to access the account.
I want to add a method in which you can call the account's balance but am not sure how to do this.
Any help would be greatly appreciated.
You aren't showing much of your Account class (which is fine -- having a Minimal Reproducible Example is good, but a fully compilable code snippet would be preferable), so my answer will go with some assumptions:
You need to be able to retrieve and set the balance.
You don't currently have a solution for this problem.
I'll assume your current class looks like this (eliminating whitespace for brevity):
public class Account {
public void createAccount(int bal, String name) {
int balance = bal;
String username = name;
System.out.println("An account has been set up for "+name+", with a balance of $"+bal+".");
}
}
As #ScaryWombat pointed out in his comment, you need to move the balance and username variables out of the createAccount method and into the class as fields. You then set these fields in the createAccount method:
public class Account {
private int balance = bal;
private String username = name;
public void createAccount(int bal, String name) {
this.balance = bal;
this.username = name;
System.out.println("An account has been set up for "+name+", with a balance of $"+bal+".");
}
}
Now, an Account instance holds a balance and a name, which is overwritten when you call createAccount.
However, we still have a problem. Every time you call createAccount, the data is overwritten. For example in this code, Bob's account will be forgotten and the data overwritten by Alice's account:
Account account = new Account();
account.createAccount(1000, "Bob");
account.createAccount(2000, "Alice");
This is where constructors come in. Instead of a createAccount method, we'll move the logic into the Account constructor:
public class Account {
private int balance = bal;
private String username = name;
public Account(int bal, String name) {
this.balance = bal;
this.username = name;
System.out.println("An account has been set up for "+name+", with a balance of $"+bal+".");
}
}
With this, the only way to create an account is to specify the starting details in the call to new Account():
Account bobsAccount = new Account(1000, "Bob");
Account alicesAccount = new Account(2000, "Alice");
However, we still haven't addressed the core of your question: How to access the balance? The following will result in an error:
bobsAccount.balance = 2000;
This is because the balance field is private (as it should be). What we need is to add accessor methods to the Account class:
public class Account{
...
public void setBalance(int newBalance) {
balance = newBalance;
System.out.println(name+"'s account balance is now $"+bal+".");
}
public int getBalance() {
return balance;
}
...
}
You might ask "why go to this trouble?", well, we can add checks (e.g. not allow a balance to go below zero), add logging to audit access to balances, or even not have a setBalance or getBalance, but only transferFrom(Account otherAccount) and transferTo(Account otherAccount) (ensuring money is never added, but only transferred around in the system).
PS. and as pointed out in other comments, int is never good for monetery amounts. What you need is a Currency type that uses something else, e.g. BigDecimal, to store the actual values.

Using a single parameter from a Super class where the super class uses more parameters

this might be something really easy to address but I am really new to Java and I am having a problem fixing this error. I am working on a basic ATM Machine (I can't go fancy just yet). I have a BankAccount class, a Checking Account (extends bankAccount), A savingsAccount class (also extends bankAccount) and a User class. In my CheckingAccount class, I want to use one of the parameters from my SUPER class (bankAccount), "balance" but I am not sure if there is a way to only use ONE parameter from a constructor that has more than One parameter. If so, any clue for how to? I am getting an Error : "no suitable constructor found for BankAccount(double)..." . This is my code so far, I appreciate your help.
-- BankAccount Class --
package atm;
public class BankAccount {
public double balance;
public int accountNumber = 333220;
public User user;
public BankAccount(){
balance = 0;
}
public BankAccount(double balance, int accountNumber, User user){
this.balance = balance;
this.accountNumber = accountNumber;
this.user = user;
}
public void accountNumber(){
accountNumber++;
}
public int getAccountNumber(){
return accountNumber;
}
public void deposit (double amount){
balance += amount;
}
public void withDraw(double amount) {
balance -= amount;
}
public double getBalance (){
return balance;
}
public void transfer( BankAccount other,double amount){
withDraw(amount);
other.deposit(amount);
}
}
-- CheckingAccount Class --
package atm;
public class CheckingAccount extends BankAccount {
private int transactionCount;
private static final double transactionFees = 1.50;
private static final int freeTransactions = 5;
public CheckingAccount (double balance){
super(balance); //HERE is where I am confused. I only need to use the "balance"
transactionCount = 0;
}
public void deposit(double amount){
transactionCount ++;
super.deposit(amount);
}
public void withDraw(double amount){
transactionCount ++;
super.withDraw(amount);
}
public void deductFees (){
if (transactionCount > freeTransactions){
double fees = transactionFees * (transactionCount - freeTransactions);
super.withDraw(fees);
}
transactionCount = 0;
}
}
Thanks a lot!
You need to create another constructor in BankAccount.java that only initializes amount like below
public BankAccount(double balance){
this.balance = balance;
}
Read about having multiple constructors in Java here
http://tutorials.jenkov.com/java/constructors.html
Since CheckingAccount is a BankAccount, it must have all the attributes of the BankAccount, including the account number and the User who owns it.
The base class requires accountNumber and user to be supplied by the derived class, so you should change the constructor to forward this information to super:
public CheckingAccount (double balance, int accountNumber, User user){
super(balance, accountNumber, user);
transactionCount = 0;
}
Note 1: In certain situations a derived class could hard-code parameters to be passed to super; this is not one of these situations.
Note 2: Consider making BankAccount abstract, and changing accessibility of its constructor from public to protected.

i can't get the right output in java

I have a problem with my program and I don't know why the names and the IDs of the objects don't show up right in the output and also the balance is not used in chkBalance() method Why ??I think the problem with the constructor but? ... and the output I get from this code is ...:
Customer Name Customer ID Balance
null 0.0 200
null 0.0 200
null 0.0 200
public class BankAccount {
private int Balance;
public String AccHolder_Name;
public double AccHolder_ID;
public BankAccount(String Name ,double ID,int Balance) {
Name = AccHolder_Name;
ID = AccHolder_ID;
}
public void withDraw(int a) {
Balance=a-Balance;
}
public void deposit(int b) {
Balance=b+Balance;
}
public int chkBalance(){
deposit(500);
withDraw(700);
return Balance;
}
public void Display () {
System.out.println(AccHolder_Name+"\t\t"+AccHolder_ID+"\t\t"+Balance);
}
public static void main (String args []) {
BankAccount o1=new BankAccount("Aos" , 1101558733 ,3000);
BankAccount o2=new BankAccount("Ahmed" , 1101978733,5000);
BankAccount o3=new BankAccount("Ali",1111650924,7000);
System.out.println("Customer Name\tCustomer ID\tBalance");
o1.chkBalance();
o2.chkBalance();
o3.chkBalance();
o1.Display();
o2.Display();
o3.Display();
}
}
In your constructor you are assigning null to the given parameters and never assign Balance
public BankAccount(String Name ,double ID,int Balance) {
Name = AccHolder_Name; // Will assign #AccHolder_Name to #Name
ID = AccHolder_ID;
}
So you should reverse this assignment and set the Balance field with the given parameter :
public BankAccount(String Name ,double ID,int Balance) {
AccHolder_Name = Name; // Will assign #Name to #AccHolder_Name
AccHolder_ID = ID;
this.Balance = Balance;
}
And about your variables names you should take a look to the naming convention.
The variables should use camel case and for good practice be well representative of their function.
So AccHolder_Name should be accHolderName for example.
Your assignments in the constructor is the wrong way arround. Also, you forgot to assign the Balance argument, which causes Balance to default to 0 and results in 200 after the calculations.
public BankAccount(String Name, double ID, int Balance) {
this.AccHolder_Name = Name;
this.AccHolder_ID = ID;
this.Balance = Balance;
}
An important note on your naming conventions: variables in Java use camel case. It is also discouraged to abbreviate variable names unless they are considered an abbreviation standard. The resulting code would then be:
public BankAccount(String name, double id, int balance) {
this.accountHolderName = name;
this.accountHolderId = id;
this.balance = balance;
}
The constructor of the BankAccount is indeed wrong. Since what '=' operation does is to give the value of the right variable to the left variable, and your code is reversed.
Another problem is that you don't initialize your Balance in your constructor and the compiler will then simply initialize it to 0.
Constructor has issue. Copy bellow code and replace your constructor and check.
public BankAccount(String Name ,double ID,int Balance) {
this.AccHolder_Name = Name;
this.AccHolder_ID = ID;
this.Balance = Balance;
}
My suggestion is to learn java more. Basic you can learn from Java Tutorial.
In the constructor you are assigning it in the other way. Assign it as below
public BankAccount(String Name ,double ID,int Balance) {
this.AccHolder_Name = Name;
this.AccHolder_ID = ID;
this.Balance = Balance;
}
There is always the variable you want to set on the left side and the value for it on the rigt side. As you want to set the String AccHolder_Name to the Name you are giving in the constructor, you have to do it just the other way around.
There are several mistakes:
a. Your constructor is incorrect and not saving the provided
variables.
this.AccHolder_Name=Name ;
this.AccHolder_ID=ID;
this.Balance=Balance;
b. Your withdraw method is incorrect. It should be (balance =
balance-a)
Please see the correct code below.
public class BankAccount {
private int Balance ;
public String AccHolder_Name;
public double AccHolder_ID;
public BankAccount(String Name ,double ID,int Balance) {
this.AccHolder_Name=Name ;
this.AccHolder_ID=ID;
this.Balance=Balance;
}
public void withDraw(int a) {
Balance=Balance-a;
}
public void deposit(int b) {
Balance=b+Balance;
}
public int chkBalance(){
deposit(500);
withDraw(700);
return Balance;
}
public void Display () {
System.out.println(AccHolder_Name+"\t\t"+AccHolder_ID+"\t\t"+Balance);
}
public static void main (String args []) {
BankAccount o1=new BankAccount("Aos" , 1101558733 ,3000);
BankAccount o2=new BankAccount("Ahmed" , 1101978733,5000);
BankAccount o3=new BankAccount("Ali",1111650924,7000);
System.out.println("Customer Name\tCustomer ID\tBalance");
o1.chkBalance();
o2.chkBalance();
o3.chkBalance();
o1.Display();
o2.Display();
o3.Display();
}
}

how would I use an if statment to change the value of an attribute?

I want to be able to give a specific value to discount depending on certain requirements like the following age: > 25 and profession = teacher / professor get 10% discount, age < 25 and gradepoint > 7 get 25% discount
this is my code so far I am using double OO paradigm:
public class customer {
//attribute definitions
private String name;
private String address;
private String profession;
private Integer age;
private Integer gradepoint;
private double discount;
//constructor
public customer(String newName, String newAddress, String newProfession, Integer newAge, Integer newGradepoint, double newDiscount)
{
setName(newName);
setAddress(newAddress);
setProfession(newProfession);
setAge(newAge);
setGradepoint(newGradepoint);
setDiscount (newDiscount);
}
//getters
public String getName()
{ return name;}
public String getAddress()
{ return address;}
public String getProfession()
{ return profession;}
public Integer getAge()
{ return age;}
public Integer getGradepoint()
{ return gradepoint;}
public double getDiscount()
{ return discount;}
//setters
public void setName (String newName)
{ name = newName;}
public void setAddress (String newAddress)
{ address = newAddress;}
public void setProfession (String newProfession)
{ profession = newProfession;}
public void setAge (Integer newAge)
{ age = newAge;}
public void setGradepoint (Integer newGradepoint)
{ gradepoint = newGradepoint;}
public void setDiscount (double newDiscount)
{ discount = newDiscount;}
//methods
}
Would I need to create a sub class called discount or each type of discount? or I can write a method directly into this customer class to control the discount?
write a method directly into this customer class to control the discount?
This. Make it a calculated field. Kill setDiscount function, kill discount variable, and make the getDiscount function into something like:
public double getDiscount() {
if (...) return ...;
if (....) return ...;
...
}
...unless you want to have this as the default discount, and still allow modification, in which case keep discount as a property, and move this whole logic into the constructor, having conditional setDiscount() calls.
Your getDiscount function would ideally do the calculation and return the appropriate discount for the current object. For example:
public double getDiscount()
{
if (getAge() < 25 && getGradepoint() > 7)
{
return .25;
}
else if // other logic...
}
Although not the simplest solution, I would abstract the discount calculation to a separate interface and class as well as having an override discount value in the customer object.
E.g.
public interface DiscountManager<T>
{
public double getDiscount(T discountObject);
}
public abstract class AbstractCustomerDiscountManager extends DiscountManager<Customer>
{
public double getDiscount(Customer customer)
{
if (customer.hasCustomDiscount()) { return customer.getDiscount(); }
else { return calculateDiscount(customer); }
}
public abstract double calculateDiscount(Customer customer);
}
public class DefaultDiscountManager extends AbstractCustomerDiscountManager
{
public double calculateDiscount(Customer customer)
{
double discount = 0;
if ((customer.getAge() != null) && (customer.getAge() < 25)) { discount += 25; }
...
return discount;
}
}
Probably over time different rules evolve. At the spot where the discounting takes place, in the order, the discount and and a reference to the rule applied should be stored together.
This kind of business logic could have its own class. A generic solution would even be to store the rule as scriptable code (BeanShell = Java, or JavaScript) and use java's scripting API. So that this kind of business logic resides more with the business managers, and the rules can be presented and edited.

Categories