Cannot access method from another java class - java

I have this Bank class
public class Bank {
public Map<String, Account> accounts;
Bank() {
accounts = new HashMap<>();
}
public void addAccount(String accountType, int accountNumber, double apr) {
accounts.put(accountType, new Account(accountNumber, apr) {
});
}
public Map<String, Account> getAccounts() {
return accounts;
}
}
and I have another class where I am trying to call the addAccount method from the Bank class
public class Processor {
Bank bank = new Bank();
public void openCheckingsAccount(String accType, int accNum, double apr) {
bank.addAccount(accType, accNum, apr);
}
}
I have a JUnit Test class to make sure I can create a new account in the Bank class with the method in my Processor class.
public class ProcessorTest {
Bank bank;
Processor processor;
#BeforeEach
void setUp() {
bank = new Bank();
}
#Test
void create_checkings_and_verify_by_id_apr() {
processor.openCheckingsAccount("checkings", 11111111, 0.6);
System.out.println(bank.accounts);
assertEquals(11111111, bank.getAccounts().get("checkings").getAccountNumber());
}
}
But the result of System.out.println(bank.accounts) is just {} and I get a java.lang.NullPointerException error when running the JUnit test.

Your Processor class has its own instance of a Bank. I guess this is not what you want. That is why when you do bank.getAccounts().get("checkings").getAccountNumber() in your unit test you get a NullPointerException. You are getting the accounts in the bank variable in your test and not the Bank object in your Processor class.
You will need to change your Processor class to receive a Bank object in its constructor as follows:
public class Processor {
private Bank bank;
public Processor(Bank bank) {
this.bank = bank;
}
public void openCheckingsAccount(String accType, int accNum, double apr) {
bank.addAccount(accType, accNum, apr);
}
}
And now also change your test accordingly:
public class ProcessorTest {
Bank bank;
Processor processor;
#BeforeEach
void setUp() {
bank = new Bank();
processor = new Processor(bank);
}
#Test
void create_checkings_and_verify_by_id_apr() {
processor.openCheckingsAccount("checkings", 11111111, 0.6);
System.out.println(bank.getAccounts());
assertEquals(11111111, bank.getAccounts().get("checkings").getAccountNumber());
}
}
Now there is only only Bank instance in your test which is changed by your Processor class.
As a side note, please avoid having public properties in your classes (example: public Map<String, Account> accounts; in your Bank class). They should be private and be accessed via methods in the class. Additionally, keep in mind that when you return the Map in Bank in your getAccounts() method the caller has now a reference to the Map and can change it however he may see fit. Having said that, you should consider returning a new Map (thanks #chrylis-cautiouslyoptimistic- for the hint on the Collections. unmodifiableMap):
public class Bank {
private Map<String, Account> accounts;
public Bank() {
accounts = new HashMap<>();
}
public void addAccount(String accountType, int accountNumber, double apr) {
accounts.put(accountType, new Account(accountNumber, apr) {});
}
public Map<String, Account> getAccounts() {
return Collections.unmodifiableMap(accounts);
}
}

Related

How to avoid an 'Interface Abstract class error'?

Here is my main class for this and I keep getting an error saying that
The abstract class has not been overridden
I have tried making the car class abstract and not overridding, I have tried to override and using an abstract class, without success. I just don't know what I'm doing wrong.
public abstract class Car implements CarbonFootprint {
private double Car;
private double MilesDrivenPerYear;
private double MilesPerGallon;
//Constructor
public Car(double MilesDrivenPerYear, double MilesPerGallon) {
this.MilesDrivenPerYear = MilesDrivenPerYear;
this.MilesPerGallon = MilesPerGallon;
}
//Return miles driven per year
public double getMilesDrivenPerYear() { return MilesDrivenPerYear; }
//Return Miles per Gallon
public double getMilesPerGallon() { return MilesPerGallon; }
public void setMilesDrivenPerYear(double MilesDrivenPerYear) {
this.MilesDrivenPerYear = MilesDrivenPerYear;
}
public void setMilesPerGallon(double MilesPerGallon) {
this.MilesPerGallon = MilesPerGallon;
}
#Override
public String toString() {
return String.format("%s: %n%s: %s", "Car", "Miles
Driven: ",getMilesDrivenPerYear(), "Miles per
Gallon; ",getMilesPerGallon());
}
public abstract double Car();
public double getCarbonFootprint() {
return Car = getMilesDrivenPerYear() / getMilesPerGallon() * 19.82;
}
}
//end car class'
public class CarbonFootprintTest {
public static void main(String[] args) {
ArrayList FootprintList = new ArrayList();
Car Footprint1 = new Car(25, 36);
FootprintList.add(Footprint1);
Building Footprint2 = new Building(78, 78);
FootprintList.add(Footprint2);
Bicycle Footprint3 = new Bicycle(90);
FootprintList.add(Footprint3);
System.out.println("Shaina Carbon Footprint Calculator");
for (Object Footprint: FootprintList) {
System.out.printf("Miles Driven:");
System.out.printf("Car Carbon Footprint",
Footprint2.getCarbonFootprint());
}
}
Car is an Abstract class, so you cannot create an instance of it. You should probably make another class that extends the Car class. See this answer for information:
https://stackoverflow.com/a/30317092/7260643

Something went wrong in my test with models, since I add a Dependency Injection

I try to make my test simpler with a DI (PicoContainer), but now it doesn't work corrctly anymore.
I get this errormassages:
java.lang.NullPointerException
at org.javalite.activejdbc.Model.setRaw(Model.java:355)
at org.javalite.activejdbc.Model.setInteger(Model.java:1740)
at cash_withdrawal.Account.(Account.java:11)
at support.TestAccount.(TestAccount.java:7)
....
support.TestAccount:
public class TestAccount extends Account {
public TestAccount() {
super(1234);
saveIt();
}
}
cash_withdrawal.Account
public class Account extends Model {
private TransactionQueue queue = new TransactionQueue();
public Account() {}
public Account(int number){
setInteger("number", number);
setString("balance", "0.00");
}
}
My Stepdefintion:
public class AccountSteps {
TestAccount account;
public AccountSteps(TestAccount account) {
this.account = account;
}
#Given("^my account has been credited with (\\$\\d+\\.\\d+)$")
public void myAccountHasBeenCreditedWith$(
#Transform(MoneyConverter.class) Money amount)
throws Throwable {
account.credit(amount);
}

How to reduce if else jungle from my controller?

I have a java controller class, when ever save action is invoked in any item say Product or coverage or Limit , it calls the controller save method and a parameter is passed. The if logic in the controller checks the argument and call the save method of the appropriate object. The if logic is increasing day by day. Can any one suggest better design pattern?
Code:
public class Product {
public void save(PolicyData p){
//logic here
}
}
public class Coverage {
public void save(PolicyData p){
//logic here
}
}
public class Limit {
public void save(PolicyData p){
//logic here
}
}
public class Controller {
private Product pr=new Product();
private Limit lim=new Limit();
private Coverage cov=new Coverage();
public void save(PolicyData p,String item){
if(item.equals("Product")){
pr.save(p);
}if(item.equals("Coverage")){
cov.save(p);
}if(item.equals("Limit")){
lim.save(p);
}
}
}
Create a Saveable interface:
public interface Saveable {
public void save(String p);
}
your classes implement the interface, and then create a Map:
private Map<String, Saveable> saveMap = new HashMap<>();
Fill it with Savable objects and then call the save method based on the String.
public enum SaveableType {
PRODUCT, COVERAGE, LIMIT
}
public class Controller {
private Product pr = new Product();
private Limit lim = new Limit();
private Coverage cov = new Coverage();
private Map<SaveableType, Saveable> saveableMap = new HashMap<>();
public Controller() {
saveableMap.put(SaveableType.PRODUCT, pr);
saveableMap.put(SaveableType.LIMIT, lim);
saveableMap.put(SaveableType.COVERAGE, cov);
}
// better to use enum for the 2nd parameter not a String
public void save(PolicyData p, String item) {
SaveableType saveables = SaveableType.valueOf(item.toUpperCase());
saveableMap.get(saveables).save(p);
}
}
Create an interface that has save method
Implement the method in your object
In your controller create a map to hold objects against the key that you are comparing now in your if
code:
public interface Myinterface {
public void save(PolicyData p);
}
public class Product implements Myinterface{
public void save(PolicyData p){
//logic here
}
public class Controller {
private static HashMap<String,Myinterface> map=new HashMap<String,Myinterface>();
public Controller(){
map.put("Product", new Product());
map.put("Limit", new Limit());
map.put("Coverage", new Coverage());
}
public void save(PolicyData p,String item){
Myinterface m=map.get(item);
m.save(p);
}
}
}
Not really a solution to reduce the if-else jungle. But this might look more "beautiful".
http://www.w3schools.com/js/js_switch.asp
So in your case:
switch(item) {
case("Product"): pr.save(item); break;
// and so on...
}

How can I create an array of instances accessible in a class?

I am writing a code that create an array of instances of Account object in another class (Bank).
I am initializing the array inside the main method, but it is not accessible inside the Bank class.
What I want to do is create 4 instances of the Account class and to be able to perform all tasks inside the Bank class methods. Is there a way that I can do this?
this is my code
Account.java
package question1;
import java.util.Date;
public class Account {
public int AccountNum;
public double BALANCE;
public Date OPENDATE;
public String OwnerName;
public Account() {
// TODO Auto-generated constructor stub
}
public Account(int accnum, double balance, Date opendate, String ownername) {
this.AccountNum = accnum;
this.BALANCE = balance;
this.OPENDATE = opendate;
this.OwnerName = ownername;
}
public int getAccountNum() {
return AccountNum;
}
public void setAccountNum(int accountNum) {
AccountNum = accountNum;
}
public double getBALANCE() {
return BALANCE;
}
public void setBALANCE(double bALANCE) {
BALANCE = bALANCE;
}
public Date getOPENDATE() {
return OPENDATE;
}
public void setOPENDATE(Date oPENDATE) {
OPENDATE = oPENDATE;
}
public String getOwnerName() {
return OwnerName;
}
public void setOwnerName(String ownerName) {
OwnerName = ownerName;
}
public double yearlyInterest(double balace) {
return balace;
}
}
Bank.java
package question1;
public class Bank {
public static void main(String[] args) {
Account[] acc = new Account[4];
for(int i = 0 ; i<acc.length; i++){
acc[i] = new Account();
System.out.println(acc[i].toString());
}
/// how to continue form here ??
}
}
Call the constructor of the Account class. Now you can set all arguments as desired. Afterwards, you can add the instance to any array or collection.
List<Account> accounts = new ArrayList<Account>(4);
Account myAccount = new Account(123, 100.5, new Date(), "dev leb");
accounts.add(myAccount);
You probably want to have a property of an Account array in your class.
You can set your property in the class body:
public class Bank {
//Set your property here.
private Account[] _acc;
//Initialize in ctor.
public Bank() {
_acc = new Account[4];
}
//....
//You can then use it as a property in your code.
//If needed outside the class, set up setter and getter methods,
//avoiding violating encapsulation.
public Account[] getAcc(){
return _acc;
}
public void setAcc(Account acc){
this._acc = acc;
}
//If you need this to be used inside main, then you must instantiate a
//Bank in main and then make all the appropriate operations there.
public static void main(String[] args) {
Bank bank = new Bank();
Account[] bankAccounts = bank.getAcc();
//....
}
}
My suggestion though is that you use an ArrayList instead:
Set the property:
private List<Account> acc;
And in constructor:
acc = new List();
In order to add an account in a class method:
acc.add(new Account());
In order to retrieve an element by indexing:
acc.get(0);
for more information, look at the ArrayList JavaDoc.
If you are not able to understand why your array that is defined inside the main is not accessible inside your Bank class, then I suggest you search more about Object-Oriented programming, Class definition, instantiation and properties accessibility and manipulation and static methods in Java.

Returning a String for a Super class' abstract method to display

The abstract method statement (in the super class) must be implemented to return a string representation of a statement.
So I've done the following:
public abstract String statement(); //The abstract method in my super class
..and the method in my subclass:
//#Override
public String statement()
{
return String.format("Account no %d has balance R%d and minimum balance R%d", accountNumber,balance,getMinBalance());
}
My main class just calls the Account class (the super class in question) as follows:
new SavingsAccount(Integer.toString(ao[i]),ao[i+1],ao[a]); //ao being the array which contains the values.
However, the console just terminates without displaying anything (I'm also not familiar with implementation).
Here's the full code:
Main:
public class AccountList
{
public static void main(String[] args)
{
int[] ao = {00000,0,0,12345,500,250,23456,230,-50,34567,340,500,45678,-320,-50,56789,-320,-500};
for(int i=0;i<ao.length;i=i+3)
{
int a = i+2;
if(ao[a]>=0)
{
new SavingsAccount(Integer.toString(ao[i]),ao[i+1],ao[a]);
}
if(ao[a]<=0)
{
new ChequeAccount(Integer.toString(ao[i]),ao[i+1],ao[a]);
}
}
}
}
Super class:
public abstract class Account implements InterestAccount
{
static String accountNumber;
int balance;
public Account()
{
accountNumber = "00000";
balance = 0;
//statement();
}
public Account(String accountNumber,int balance)
{
setAccountNum(accountNumber);
setBalance(balance);
}
public void setAccountNum(String accNum)
{
accountNumber = accNum;
}
public void setBalance(int balance)
{
this.balance = balance;
}
public String getAccountNumber()
{
return accountNumber;
}
public int getBalance()
{
return balance;
}
public abstract String statement();
}
One of the sub-classes:
public class SavingsAccount extends Account
{
int minBalance;
public SavingsAccount()
{
super();
minBalance = 0;
}
public SavingsAccount(String accountNum,int minBalance,int balance)
{
super(accountNum,balance);
setMinBalance(minBalance);
}
public void setMinBalance(int minBalance)
{
this.minBalance = minBalance;
}
public int getMinBalance()
{
return minBalance;
}
#Override
public int calculateInterest(int value) {
if(minBalance>balance)
{
return 0;
}
else
{
return (minBalance*balance)/100;
}
}
//#Override
public String statement()
{
return String.format("Account no %d has balance R%d and minimum balance R%d", accountNumber,balance,getMinBalance());
}
}
You never calls the method statement.
1) create a new SavingsAccount object
new SavingsAccount(Integer.toString(ao[i]),ao[i+1],ao[a]);
2) Constructor class got call by above statement
public SavingsAccount(String accountNum,int minBalance,int balance)
{
super(accountNum,balance);
setMinBalance(minBalance);
}
3) Subclass then call superclass method
public Account(String accountNumber,int balance)
{
setAccountNum(accountNumber);
setBalance(balance);
}
4) SetBalance is called
public void setBalance(int balance)
{
this.balance = balance;
}
5) setMinBalance called
public void setMinBalance(int minBalance)
{
this.minBalance = minBalance;
}
6) End of create object SavingsAccount
No single statement calling the method statement
It might help to know more of your code, but from what I see, there are some possible cases:
Your code runs and terminates without an error. Reason you don't see anything is, there is nothing written to the standard output stream (e.g. via System.out.println()).
Your code has some internal problems, which cause an exception, which again is not shown due to a broken logging mechanism.
In any case, use a debugger to step through you code and determine which parts run perfectly and if any fail. It might help to extract some local variables, give them proper meaningful names and watch their contents during execution.

Categories

Resources