Java, inheritance

brutetal

New Member
Messages
23
Reaction score
1
Points
0
For my java class, we're doing a project based on inheritance.

I can get my code to update the balanceFloat and display it.
But it won't output the string objects. @.@

This is just a modified version of the full code.

Design class:
Code:
JTextArea transactionsTextArea = new JTextArea(10,10);
//Instance Variable
int accountInteger = 0;
//Array
BankAccount[] accounts = new BankAccount[10];
public void intializeTextArea(){
//Example account
accounts[0] = new BankChecking("name","last", "0000", 100.0f, 1); 

        String accountTypeString = null;
        DecimalFormat currencyFormat = new DecimalFormat("$#0.00");
        transactionsTextArea.setText("");
        if(accounts[accountInteger].getAccountType() == 1){
            accountTypeString = "Checking";
        }else if(accounts[accountInteger].getAccountType() == 2){
            accountTypeString = "Savings";
        }
        transactionsTextArea.append("Account Type: " + accountTypeString + "   Balance: " + currencyFormat.format(accounts[accountInteger].getBalance()) + "\n");
        transactionsTextArea.append("First Name: " + accounts[accountInteger].getFirstName() + "Last Name:" + accounts[accountInteger].getLastName() + "Pin Code:" + accounts[accountInteger].getPinCode() + "\n");
        transactionsTextArea.append("----------------------------------------------------------\n");
        
        
    }
BankAccount class
Code:
public abstract class BankAccount {
    protected static String firstNameString, lastNameString, pinCodeString;
    protected int typeAccountInteger;
    protected static float balanceFloat;
    
    protected BankAccount(String firstNameString, String lastNameString, String pinCodeString,float balanceNewFloat, int typeNewInteger){
        setFirstName(firstNameString);
        setLastName(lastNameString);
        setAccountType(typeNewInteger);
        setPinCode(pinCodeString);
        setBalance(balanceNewFloat);
        
    }
    protected BankAccount(float balanceNewFloat){
        setBalance(balanceNewFloat);
    }
    protected void setFirstName(String firstNameString){
        this.firstNameString = firstNameString;
    }
    protected void setLastName(String lastNameString){
        this.lastNameString = lastNameString;
    }
    protected void setPinCode(String pinCodeString){
        this.pinCodeString = pinCodeString;
    }
    protected void setBalance(float balanceNewFloat){
        this.balanceFloat = balanceNewFloat;
    }
    protected void setAccountType(int typeNewInteger){
        this.typeAccountInteger = typeNewInteger;
    }
    protected String getFirstName(){
        return firstNameString;
    }
    protected String getLastName(){
        return lastNameString;
    }
    protected String getPinCode(){
        return pinCodeString;
    }
    protected float getBalance(){
        return balanceFloat;
    }
    protected int getAccountType(){
        return typeAccountInteger;
    }
}

BankChecking subClass
Code:
public class BankChecking extends BankAccount {
    
    public BankChecking(String firstNameString, String lastNameString,
            String pinCodeString, float balanceNewFloat, int typeAccountInteger) {
        super(firstNameString, lastNameString, pinCodeString, balanceNewFloat, typeAccountInteger);
        
    }
    public void withdraw(float balanceNewFloat){
        float feeFloat = 0.50f;
        if(balanceNewFloat > 750.0f){
            BankAccount.balanceFloat =  BankAccount.balanceFloat - balanceNewFloat - feeFloat;
        }else{
            BankAccount.balanceFloat =  BankAccount.balanceFloat - balanceNewFloat;
        }
    }
    public void deposit(float balanceNewFloat){
        BankAccount.balanceFloat = BankAccount.balanceFloat + balanceNewFloat;
    }
    public String getFirstName(){
        return firstNameString;
    }
    public String getLastName(){
        return lastNameString;
    }
    public String getPinCode(){
        return pinCodeString;
    }
    public float getBalance(){
        return balanceFloat;
    }
    public int getAccountType(){
        return typeAccountInteger;
    }

}

BankSavings subClass
Code:
public class BankSaving extends BankAccount {

    public BankSaving(String firstNameString, String lastNameString,
            String pinCodeString, float balanceNewFloat, int typeAccountInteger) {
        super(firstNameString, lastNameString, pinCodeString, balanceNewFloat, typeAccountInteger);
        
    }
    public void withdraw(float balanceNewFloat){
        float feeFloat = 0.75f;
        if(balanceNewFloat > 2000.0f){
            BankAccount.balanceFloat =  BankAccount.balanceFloat - balanceNewFloat - feeFloat;
        }else{
            BankAccount.balanceFloat =  BankAccount.balanceFloat - balanceNewFloat;
        }
    }
    public void deposit(float balanceNewFloat){
        BankAccount.balanceFloat = BankAccount.balanceFloat + balanceNewFloat;
    }
    public String getPinCode(){
        return pinCodeString;
    }

}

Output:
Code:
Account Type: Checking   Balance: $100.00
First Name: Last Name:Pin Code:
----------------------------------------------------------
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
The sample code printed the first and last names and PIN when I ran it (after minor modifications to make it compile; test cases should be self contained and compilable as-is). Test your sample yourself; if it works, compare it to your full code.

Code:
        if(accounts[accountInteger].getAccountType() == 1){
            accountTypeString = "Checking";
        }else if(accounts[accountInteger].getAccountType() == 2){
            accountTypeString = "Savings";
        }
Type sniffing is almost always the wrong thing; polymorphism is almost always the right thing. Add a method that returns the name of the account type.

Code:
public class BankChecking extends BankAccount {
    public void withdraw(float balanceNewFloat){
        float feeFloat = 0.50f;
        if(balanceNewFloat > 750.0f){
Magic numbers are generally to be avoided. The withdrawal fee and the penalty-incurring amount could easily be made class constants or members.

Variable names shouldn't hold the actual type (e.g. "...Float", "...String"), as that may change, but may have a type that indicates usage (e.g. "accountTypeName" instead of "accountTypeString" and "accountTypeCode" rather than "typeAccountInteger"; see "Systems vs. Apps Hungarian").

Code:
    public String getFirstName(){
    [...]
Why are you overriding these getters since you're not changing the implementation?

Accessors (getters & setters) can cause problems. Make sure you understand the costs and benefits.
 
Last edited:

brutetal

New Member
Messages
23
Reaction score
1
Points
0
Oh its my professor who wants us to do that as part of her guidelines for each project. Adding the data type's whole name to the end of the variable name. I would lose points on the overall project or not get graded at all until I fix it what I don't follow according to her guidelines.

Alright, I'll double check the sample.

Edit:
Yep, I called the method before I added the object to the array.
Okay that fixed it.

Next problem:
Its suppose to check the pin number with the input and the one in the array if it matches.

Code:
public boolean verifyLogin(){
		boolean verifyBoolean = false, foundBoolean = false;
		int pinCodeInteger, indexInteger = 0;
		try{
			//Only for use to check if the input is an integer.
			pinCodeInteger = Integer.parseInt(pinLoginTextField.getText());
			if(pinLoginTextField.getText().length() == 4){
				while(foundBoolean == false && indexInteger < accounts.length){
					if(accounts[indexInteger].getPinCode() == pinLoginTextField.getText()){
						foundBoolean = true;
						verifyBoolean = true;
						accountInteger = indexInteger;
						//For testing usage
						JOptionPane.showMessageDialog(null, "Found User.  " + accountInteger);
					}else{
						indexInteger++;
					}
				}
				if(foundBoolean == false){
					JOptionPane.showMessageDialog(null, "Could not find pin.");
				}
			}else{
				JOptionPane.showMessageDialog(null, "Please enter a valid pin code.");
				pinRegTextField.requestFocus();
			}
		}catch(NumberFormatException exception){
			JOptionPane.showMessageDialog(null, "Please enter a valid pin code. ");
			pinRegTextField.requestFocus();
		}
		return verifyBoolean;
	}

It only displays. "Could not find pin."
I've tried a few other ways but still no luck.

Edit:
Ahh... I remember now.
I forgot about .equals()
*face palm*

Another problem:
It doesn't let me add more than one account into the array.
If the first name in the first key in the array is filled, then it just counts the numbers until it hits the end.

Code:
	public void registerAccount(){
		boolean foundBoolean = false;
		String firstNameString = firstNameTextField.getText(), lastNameString = lastNameTextField.getText(), pinCodeString = pinRegTextField.getText();
		int indexInteger = 0, selectedInteger = typeComboBox.getSelectedIndex();
		float balanceNewFloat = 0.0f;
		while(foundBoolean == false && indexInteger < accounts.length){
			if(accounts[indexInteger].getFirstName().equals("")){
				foundBoolean = true;
				this.accountInteger = indexInteger;
				JOptionPane.showMessageDialog(null, "Found User.  " + accountInteger);
			}else{
				indexInteger++;
                                JOptionPane.showMessageDialog(null, "Count " + indexInteger);
			}
		}
		if(foundBoolean){
			if(selectedInteger == 0){
				balanceNewFloat = 100.0f;
				accounts[indexInteger] = new BankChecking(firstNameString, lastNameString, pinCodeString, balanceNewFloat, "Checking");
			}else if(selectedInteger == 1){
				balanceNewFloat = 500.0f;
				accounts[indexInteger] = new BankSaving(firstNameString, lastNameString, pinCodeString, balanceNewFloat, "Savings");
			}
		}
	}

So what do I need to change for the condition in the IF statement?
I've tried other things but still the same result.

Edit:
Okay, I got help.
I left the accounts array empty
and used if(accounts[indexInteger]==null) instead.
It works just the way I need it to.
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
Oh its my professor who wants us to do that as part of her guidelines for each project. Adding the data type's whole name to the end of the variable name. I would lose points on the overall project or not get graded at all until I fix it what I don't follow according to her guidelines.
Too bad. There's not much you can do when your professor forces you to follow bad practices. Depending on how open minded she is, you could see why she has that particular guideline and (once you've studied why Systems Hungarian Notation is bad but Apps Hungarian can be useful, and assuming she doesn't have any compelling reasons) perhaps change her mind.

Another problem:
It doesn't let me add more than one account into the array.
If the first name in the first key in the array is filled, then it just counts the numbers until it hits the end.
Are firstNameString, lastNameString, pinCodeString and balanceFloat in BankAccount still static? That will cause problems. If you aren't doing it now, start using a debugger. They are very helpful in finding out exactly what your code is doing.

Edit:
Okay, I got help.
I left the accounts array empty
and used if(accounts[indexInteger]==null) instead.
It works just the way I need it to.
This is a better approach, but you'll still have problems leaving those fields static.

Rather than scanning the account array each time, store the index of the last account or the next empty account. With a maximum of 10 accounts, you won't notice a difference, but with millions, O(1) is much better than O(n).

Code:
if (selectedInteger == 0) {
	balanceNewFloat = 100.0f;
	accounts[indexInteger] = new BankChecking(firstNameString, lastNameString, pinCodeString, balanceNewFloat, "Checking");
}else if(selectedInteger == 1){
	balanceNewFloat = 500.0f;
	accounts[indexInteger] = new BankSaving(firstNameString, lastNameString, pinCodeString, balanceNewFloat, "Savings");
}
More magic numbers combined with basically the same problems as type sniffing. At the very least, you should get a value from the combo box that more directly reflects the type of the account (e.g. a string naming the type or a BankAccount account type code constant). What would be ideal is a polymorphic constructor, but sadly they don't exist (and can't exist, really). Instead, you can apply the factory pattern and have a class with a method that can produce different types of concrete account objects.

The foundBoolean local in verifyLogin and registerAccount is completely unnecessary. You can use break or return to exit a loop early, any if (foundBoolean) block can be integrated into the block that currently sets foundBoolean, and any if (! foundBoolean) block (comparing to false in Java is just unnecessarily verbose) can be placed after the loop sans the if.

Code:
int i;
for (i=0; i < accounts.length; ++i) {
    if (predicate(accounts[i])) {
        return process(accounts[i]);
        // or possibly "break;"
    }
}
// no account found
// if you break out of the loop, you must check that no account was found
//if (i >= accounts.length) {
    ...
//}

Note you could abstract out the search function:
Code:
interface Functor<Result, Arg> {
    Result call(Arg a);
}

class MatchPIN implements Functor<Boolean, BankAccount> {
    private String pin;
    MatchPin(String p) {
	pin=p;
    }
    public Boolean call(BankAccount account) {
	return account.getPinCode().equals(this.pin);
    }
}
...
    BankAccount findAccount(Functor<Boolean, BankAccount> predicate) {
	for (int i=0; i < accounts.length; ++i) {
	    if (predicate.call(accounts[i])) {
		return accounts[i];
	    }
	}
	return null;
    }
    ...
    boolean verifyLogin(String pin) {
        return null == findAccount(MatchPIN(pin));
    }
Note that code dealing with user interface objects has been left out of the sample, which solely reflects the business logic. This is part of separation of concerns; since the user interface and business logic are different concerns, they are placed in different classes. class MatchName and findAccountNumber left as an exercise.
 
Top