Java中的抽象类 - 创建方法

时间:2016-04-02 17:27:26

标签: java oop object abstract-class abstract

我对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类?

1 个答案:

答案 0 :(得分: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和大多数其他OOP语言中的常见约定。养成遵循此约定以帮助其他人阅读您的代码的习惯是很好的。