Подкласс не наследует все методы

У меня есть класс под названием «Учетная запись»:

import java.util.Date;

public class Account {

    public int id = 0; //Declare default id as 0
    public double balance = 0; //Declare default balance as 0
    public double annualInterestRate = 0; //Declare default annual interest rate as 0
    public Date dateCreated = new Date(); //Declare date

    //No argument constructor for Account
    public Account() {
    id = 0;
    balance = 0.0;
    annualInterestRate = 0.0;
    }   

    //Constructor that accepts ID, Balance, and Annual Interest Rate
    public Account(int newID, double newBalance, double newAnnualInterestRate) {
    id = newID;
    balance = newBalance;
    annualInterestRate = newAnnualInterestRate;
    }  

    //Get ID
    public int getId() {
        return id;
    }

    //Set ID
    public void setId(int id) {
        this.id = id;
    }

    //Get Balance
    public double getBalance() {
        return balance;
    }

    //Set Balance
    public void setBalance(double balance) {
        this.balance = balance;
    }

    //Get Annual Interest Rate
    public double getAnnualInterestRate() {
        return annualInterestRate;
    }

    //Set Annual Interest Rate
    public void setAnnualInterestRate(double annualInterestRate) {
        this.annualInterestRate = annualInterestRate;
    }

    //Get Date Created
    public Date getDateCreated() {
        return dateCreated;
    }

    //Withdraw method
    double withdraw(double amount) {
    return balance -= amount;
    }

    //Deposit method 
    double deposit(double amount) {
    return balance += amount;
    }

    //Interest rate method
    double getMonthlyInterestRate() {
    return (balance * annualInterestRate) / 12;
   }

} //End Account class 

Затем я создал два разных подкласса «PreferredCustomer» и «CommercialCustomer». Эти два класса должны наследовать все методы (депозит, вывод, ежемесячная процентная ставка, а также все геттеры и сеттеры) основного класса «Учетная запись». Единственная разница с подклассами заключается в том, что они имеют заранее определенную процентную ставку.

public class PreferredCustomer extends Account {

    public double annualInterestRate;

    public PreferredCustomer() {
    }

    public PreferredCustomer(int id, double balance) {
    super();
    this.annualInterestRate = .04;
    }

} //end PreferredCustomer Class

У меня есть ощущение, что то, как я сейчас настроил его, не является точным. При тестировании методы вывода и депозита работают, но, несмотря на ввод начального баланса в 20 000 долларов, он по-прежнему устанавливает начальный баланс в 0 долларов и не рассчитывает процентную ставку.

Я тестирую класс как таковой:

public class TestingAccountClass {

public static void main(String[] args) {

    //Create accounts
    CommercialCustomer myCommercialCustomerAccount = new CommercialCustomer(1124, 
          20000.00);

   //Invoking deposit method from account class
   myCommercialCustomerAccount.deposit(3000.00);

   //Display account balance, monthly interest, and date created
   System.out.println("\n\n----Commercial Account---");
   System.out.println("Account Created On: "
       + myCommercialCustomerAccount.getDateCreated());
   System.out.printf("Balance: $%.2f", myCommercialCustomerAccount.getBalance());
   System.out.printf("\nMonthly Interest: $%.2f"
       ,myCommercialCustomerAccount.getMonthlyInterestRate());

При тестировании класса таким образом метод депозита работает, но ничего из класса аккаунта (кроме вывода) не работает. Любой совет будет принят во внимание. Спасибо!


person mjmiller814    schedule 23.04.2013    source источник
comment
PreferredCustomer не должен определять annualInterestRate — он наследует annualInterestRate Пользователя. Кроме того, PreferredCustomer должен звонить super(id, balance, .04)   -  person Zim-Zam O'Pootertoot    schedule 24.04.2013
comment
На данный момент, если я уберу код годовой процентной ставки, он все равно не выдаст правильный баланс :( Дело в том, что подкласс должен иметь свою собственную процентную ставку, а не наследовать процентную ставку основного класса. Разве это невозможно?   -  person mjmiller814    schedule 24.04.2013


Ответы (4)


Вы делаете:

CommercialCustomer myCommercialCustomerAccount = new CommercialCustomer(1124, 20000.00);

Тем не мение,

public PreferredCustomer(int id, double balance) {
    super();
    this.annualInterestRate = .04;
}

Вы ничего не делаете с балансом!

Возможно, вы могли бы изменить его на:

public PreferredCustomer(int id, double balance) {
    super();
    this.balance = balance;
    this.annualInterestRate = .04;
}

Но вы бы написали balance дважды.

Кроме того, плохая идея иметь две переменные с одинаковым именем (базовая и дочерняя) -> annualInterestRate.

РЕДАКТИРОВАТЬ ------------------------------------------ РЕДАКТИРОВАТЬ

Я бы порекомендовал что-то вроде этого:

public Account() {
    this(0, 0d, 0d);
}  

public Account(int id, double balance, double interestRate) {
    this.id = id;
    this.balance = balance;
    this.annualInterestRate = interestRate;
}   

public PreferredCustomer(int id, double balance) {
    super(id, balance, 0.04d);
}

РЕДАКТИРОВАТЬ2 ----------------------------------------- РЕДАКТИРОВАТЬ2

Это не правильно. Вы выполняете целочисленное деление.

return (balance * annualInterestRate) / 12;

Измените на это:

return (balance * annualInterestRate) / 12d;

или это:

return (balance * annualInterestRate) / 12.0;
person jn1kk    schedule 23.04.2013
comment
Я прошу прощения, если это кажется немного тривиальным, студент колледжа, поэтому я все еще учусь :) Я думаю, что у меня может быть неправильное понимание того, как построить подкласс. В настоящее время я настроил его аналогично примерам, которые дал мне мой профессор, но, очевидно, мне не хватает чего-то большего :/ - person mjmiller814; 24.04.2013
comment
Это, кажется, в основном исправить это. Баланс сейчас обновляется, но проценты по-прежнему не начисляются. Вернусь к чертежной доске, я полагаю :) - person mjmiller814; 24.04.2013
comment
Большое спасибо, это сработало отлично. Теперь я понимаю, где я ошибся, так что спасибо. - person mjmiller814; 24.04.2013

В PreferredCustomer нет механизма настройки баланса; вы игнорируете аргумент конструктора balance. Вы не присвоили переменную экземпляра balance напрямую и не вызвали конструктор суперкласса. Значит баланс 0.

В конструкторе PreferredCustomer либо вызвать конструктор суперкласса, который задает баланс, либо задать его там в самом конструкторе, либо вызвать setBalance.

person rgettman    schedule 23.04.2013

Я думаю, что проблема где-то здесь:

public PreferredCustomer(int id, double balance) {
    super();
    this.annualInterestRate = .04;
    }

Разве вы не должны что-то добавить в вызов super()? (значения по умолчанию)

person Pol0nium    schedule 23.04.2013

ТРЕВОГА!

Для начала вы НИКОГДА не делаете свои неконечные переменные-члены общедоступными. У меня чуть не случился сердечный приступ.

когда вы печатаете

this.foo

Область действия продолжает подниматься вверх по дереву свойств, пока не найдет доступный элемент. Итак, это --> супер --> супер.супер --> супер.супер.супер --... и т.д.

Я могу рассказать вам, как синтаксически решить вашу проблему или рассказать вам, как сделать это намного лучше.

Я выбираю позднее.

объявить

public abstract double getAnnualInterestRate(); 

в вашем базовом классе

затем измените свою реализацию getMonthlyInterestRate как таковую (вызывая этот новый метод)

   //Interest rate method
    double getMonthlyInterestRate() {
    return (balance * getAnnualInterestRate()) / 12;
   }

в вашем подклассе просто реализуйте этот абстрактный метод и верните свою процентную ставку.

Это позволит вам полиморфно изменять скорость и сделает вашу реализацию перспективной. Функции могут делать что угодно, чтобы получить возвращаемое значение, где переменная-член представляет собой просто бит данных и ничего более.

И, пожалуйста, сделайте все ваши переменные-члены закрытыми

person Christian Bongiorno    schedule 23.04.2013
comment
Я, безусловно, ценю совет, хотя я полагаю, что моих знаний немного не хватает. Что конкретно вы подразумеваете под НИКОГДА не публиковать свои неокончательные переменные-члены? Вы имеете в виду переменные в моем классе Account, такие как идентификатор, баланс и т. д.? Когда я изначально создавал класс Account, я сделал эти переменные закрытыми, однако у меня сложилось впечатление, что их необходимо установить в Public, чтобы они были унаследованы основным классом. Я немедленно это исправлю :) - person mjmiller814; 24.04.2013
comment
Еще немного не так. Вы все еще выполняете целочисленное деление здесь. - person jn1kk; 24.04.2013
comment
Если сделать их общедоступными, они, безусловно, станут доступными для подклассов. Однако это также сделает их доступными для всего мира. Переменные-члены представляют внутреннее состояние вашего объекта, и этот объект должен когда-либо манипулировать ими только с помощью поддерживаемых им механизмов (например, сеттеров) или вообще без них (в идеале). Управление доступом к переменным в методе ограничивает, где и как можно манипулировать данными, и позволяет вам делать такие вещи, как проксирование, отложенная проверка загрузки и т. д. Следите за мной для обсуждения. Традиционно доступ к подклассу осуществляется путем объявления защищенного члена. - person Christian Bongiorno; 25.04.2013