1
public class Account {
    double currentBalance;
    
    Account(double currentBalance) {
        this.currentBalance = currentBalance; 
    }
    
    double getBalance() {
        return(this.currentBalance);
    }
    
     void deposit(double amount) {
        this.currentBalance += amount;
    }

    void withdraw(double amount) {
        this.currentBalance -= amount;
    }
    
    public String toString() {
        return("Your current account balance is: $" + this.currentBalance);
    }
}
 public class SavingsAccount extends Account {
    double interestRate;

    SavingsAccount(double interestRate, double amount) {
        super(amount);
        this.interestRate = interestRate;
    }

    void addInterest(double interestRate) {
        this.currentBalance = this.currentBalance + (this.currentBalance * (interestRate / 100));
    }
    
    public String toString() {
        return("Your current account balance is: $" + this.currentBalance + ". Your interest rate is: " + this.interestRate + "%");
    }
}
public class AccountTester {
    public static void main(String[] args) {
        System.out.println("Welcome to the COMP 251 BANK");
        
        Account[] acc = new Account[10];

        acc[0] = new Account (100000); // initial amount of 100k
        System.out.println(acc[0].toString());
        
        acc[0].deposit(50000); //deposit 50k
        System.out.println("Current balance after depositing is: " + "$" + acc[0].getBalance());
        
        acc[0].withdraw(10000);
        System.out.println("Current balance after withdrawing is: " + "$" + acc[0].getBalance());
        
        System.out.println();
        System.out.println("CHECKING ACCOUNT");

        acc[1] = new CheckingAccount(10000,50000); //overdraft limit of 1000, initial amount of 50k
        System.out.println(acc[1].toString());
        
        acc[1].deposit(20000); //I dont know what to do about the chequeDeposit 
        System.out.println("Current balance after depositing is: " + "$" + acc[1].getBalance()); 
        
        System.out.println();
        System.out.println("SAVINGS ACCOUNT");

        acc[2] = new SavingsAccount(10, 50000);
        System.out.println(acc[2].toString());

        acc[2].deposit(10000);
        System.out.println("Current balance after depositing is: " + "$" + acc[2].getBalance()); 
        
        acc[2].addInterest();
    }
}

I'm still new to this so I'm sorry if this is a bad question but I tried playing around with each class and I still can't figure out how to use the addInterest method I created in the SavingsAccount class that extends the Account class. I tried SavingsAccount.addInterest but I get a static reference error. I thought acc[2].addInterest would work but it says its undefined for the type Account.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • https://stackoverflow.com/questions/7869006/import-a-custom-class-in-java Maybe kayser his comment wil help you? – Romeo Beun May 10 '22 at 09:10
  • 1
    If you know that `acc[2]` is a `SavingsAccount`, you can cast it before calling the method, by writing something like `((SavingsAccount) acc[2]).addInterest(15);` – Dawood ibn Kareem May 10 '22 at 09:16
  • Hi! this link will help you: https://stackoverflow.com/questions/49518092/how-to-use-methods-from-extended-class-on-objects-from-main-class-java – samnoon May 10 '22 at 09:35

2 Answers2

2

You need to cast acc[2] to SavingsAccount before calling the method.

((SavingsAccount) acc[2]).addInterest();

It is called downcasting and here is an explanation of it.

Dj0ulo
  • 440
  • 4
  • 9
2

You're trying to invoke a child class' method, addInterest from a base class reference.

In fact, your array has been declared as an array of Account objects

Account[] acc = new Account[10];

This class does not offer the addIntereset method, even though your arr[2] contains a SavingAccount instance, Java in fact will only be able to know this at run-time. At compile time, your syntax must be compliant with the declared type (Account).

To work around this problem you have two solutions: creating a generic addInterest method in your base class which your child classes will override or cast your arr[2] to a SavingAccount instance.

With the first approach, you're offering an addInterest method from the base class, so whatever instance is going to call the method (an actual Account or a subtype), it will always be able to invoke it.

public class Account {
    
    public void addInterest(double interest){
        //Account implementation
    }
}

public class SavingAccount {
    
    @Overrride
    public void addInterest(double interest){
        //SavingAccount implementation
    }
}

So, in your main you could type with no errors:

Account[] arr = new Account[10];
arr[0] = new Account();
arr[0].addInterest(5);  //No error, dynamic dispatch will call Account's implementation

arr[1] = new SavingAccount();
arr[1].addInterest(10);  //No error, dynamic dispatch will call SavingAccount's implementation

With the second approach instead, you need to make sure that what you're downcasting corresponds to the subtype of your casting.

//Randomly assigning to acc an Account instance or a SavingAccount instance
Account acc = Math.round(Math.random()) == 0 ? new Account() : new SavingAccount();

//Making sure to downcast acc to SavingAccount with the instanceof operator
if (acc instanceof SavingAccount){
    SavingAccount savAcc = (SavingAccount) acc;
    savAcc.addInterest(5);
}
Dan
  • 3,647
  • 5
  • 20
  • 26