2016-04-02 2 views
0

У меня вопрос об абстрактных классах на Java. я создал абстрактный класс, как это:Аннотация класс в Java - методы создания

public class userClass { 
private String email; 
String accountType; 
account account; 

public userClass(String email, String accountType){ 
    this.setEmail(email); 
    this.setAccountType(accountType); 

    if(accountType.equals("basic")){ 
      this.account = new basicAccount(); 
    } 
    else if(accountType.equals("premium")){ 
      this.account = new premiumAccount(); 
    } 
} 

Как вы видите, у меня есть счета двух типов: базовый и премиум, они являются расширениями счета абстрактного класса. Теперь я хотел бы добавить метод только к классу премиум-класса, но когда я пытаюсь это сделать, я получаю сообщение об ошибке, что я должен реализовать его в классе учетной записи, чего я не хочу. Можно ли это сделать другим способом? Чтобы не вводить пустые методы в учетные записи и классы basicAccount?

+4

Класс не является «абстрактным» ... Вы разместили правильный код? – Tunaki

+2

Нет причин, по которым вы не можете добавить метод к одному расширению абстрактного класса, но не в базовом классе. Пожалуйста, напишите фактический код, который дает вам ошибку для получения дополнительной справки. – nhouser9

+0

добавьте определение 'account' Class. –

ответ

2

Таким образом, вы, если у вас есть Account класс, как:

public abstract class Account{ 
    public abstract void doSomethingAccountLike(); 
    //more stuff 
} 

Вы можете иметь дочерние классы:

public class BasicAccount extends Account{ 
    public void doSomethingAccountLike(){ 
     //implementation specific to basic accounts 
    } 
} 

public class PremiumAccount extends Account{ 
    public void doSomethingAccountLike(){ 
     //implementation specific to premium accounts 
    } 

    public void doSomethingPremiumLike(){ 
     //something that only makes sense 
     // in the context of a premium account 
    } 
} 

метод doSomethingPremiumLike() доступен только тогда, когда у вас есть экземпляр PremiumAccount, а именно:

public class AccountDemo{ 
    public static void main(String[] args){ 
     PremiumAccount premium = new PremiumAccount(); 
     BasicAccount basic = new BasicAccount(); 
     Account generalAccount = premium; 

     //valid- the compiler knows that the 
     //premium object is an instance of the 
     //premium class 
     premium.doSomethingPremiumLike(); 

     //Would cause a compile error if uncommented. 
     //The compiler knows that basic is an instance 
     //of a BasicAccount, for which the method 
     //doSomethingPremiumLike() is undefined. 
     //basic.doSomethingPremiumLike(); 

     //Would generate a compiler error if uncommented. 
     //Even though generalAccount actually refers to 
     //an object which is specifically a PremiumAccount, 
     //the compiler only knows that it has a reference to 
     //an Account object, it doesn't know that it's actually 
     //specifically a PremiumAccount. Since the method 
     // doSomethingPremiumLike() is not defined for a general 
     //Account, this won't compile 
     //generalAccount.doSomethingPremiumLike(); 

     //All compile- all are instances of Account 
     //objects, and the method doSomethingAccountLike() 
     //is defined for all accounts. 
     basic.doSomethingAccountLike(); 
     premium.doSomethingAccountLike(); 
     generalAccount.doSomethingAccountLike(); 
    } 
} 

Ваш вопрос

Звучит так, как будто у вас есть проблема, что в классе UserClass у вас есть поле Account account. В вашем конструкторе вы назначаете либо new BasicAccount(), либо new PremiumAccount() в поле account. Это прекрасно, но как только вы это сделаете, компилятор больше не знает в любом случае, имеет ли поле account экземпляр PremiumAccount или BasicInstance. Это означает, что если вы попытаетесь позвонить account.doSomethingPremiumLike(), вы получите ошибку компилятора. Вы можете обойти это ограничение на время выполнения:

В UserClass где-то:

if(account instanceof PremiumAccount){ 
    //if we're sure that account is actually a PremiumAccount, 
    //cast it to a PremiumAccount here to let the compiler know 
    //that doSomethingPremiumLike() can be called 
    ((PremiumAccount)account).doSomethingPremiumLike(); 
} 

Примечание: Я изменил имена ваших классов начинать с прописных букв, как это общее соглашение в Java и большинство других языков ООП. Приятно привыкнуть следовать этому соглашению, чтобы помочь другим прочитать ваш код.

+0

Да, точно. Вот как это выглядит, но в моем коде, когда я создаю объект, я делаю это с помощью учетной записи newAccount = new basicAccount(); и из-за этого я получаю сообщение о том, что я должен поместить этот новый метод doSomethingPremiumLike() также внутри абстрактного метода учетной записи (и что следует в basicAccount, чего я бы хотел избежать) – gariaable

+0

Вы должны создать его наоборот - Базовая учетная запись = новый PremiumAccount(). Затем добавьте переменную учетной записи в PremiumAccount, если вы хотите использовать какой-то конкретный метод. – Wukash

+0

Но можно ли создать объект таким образом? Eclipse показывает мне, что для создания нового объекта premiumAccount() он должен быть похож на «учетную запись» или «basicAccount accont» – gariaable

Смежные вопросы