2014-04-08 133 views
0

我想設計一個抽象類,它將強制執行實例變量的實現,即使該類型的實例變量在抽象級別未知。例如:從Java中的抽象類實施實例變量的實現

public abstract class AbstractDiet{ 
    abstract void computeMeat() 
    abstract void computeVeggies() 
    … 
} 

public abstract class AbstractAnimal{ 
    protected AbstractDiet diet; 
    … 
} 

然後我想用戶實現類似:

public class Cat extends AbstractAnimal{ 
    protected CatFoodDiet diet; // CatFoodDiet extends AbstractDiet 
    … 
} 

這是落實diet變量的最佳方式?我想確保AbstractDiet的一個子類總是在AbstractAnimal的子類中實現。

+2

'我想確保AbstractDiet的一個子類總是在AbstractAnimal的子類中實現的。'這個語句沒有意義。您不需要實現變量或字段。你初始化它。你真的在問什麼? –

+0

我想確保AbstractDiet的子類存在於任何子類AbstractAnimal中。由於AbstractDiet本身就是一個抽象類,所以我想設計一種方式,以便用戶始終知道要聲明AbstractDiet的具體子類。那有意義嗎? – user3512559

+0

我想他在問[抽象類和接口](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)之間的區別。 – user3334690

回答

1

首先:保持你的實例變量是私有的,並提供訪問器方法。

其次:聽起來好像你正在試圖定義一個接口。隨時隨地使用界面,例如「每個動物都有節食​​」。

interface Animal { 
    Diet getDiet(); 
    ... 
} 

如果你喜歡,你還可以將波西米亞的想法,並使其通用性。

interface Animal<D extends Diet> { 
    D getDiet(); 
    ... 
} 

這樣的話,你將有最大的自由度,當談到時間來定義不同種類的動物

class Cat implements Animal<CatDiet> { 
    CatDiet getDiet() { return...; } 
} 
+0

謝謝。這正是我需要的解決方案。 – user3512559

1

你不能(也不應該)像這樣設計。使用抽象類,嘗試這樣的事情:

public abstract class AbstractDiet { 
    abstract void compute(); 
} 
public abstract class AbstractAnimal<T extends AbstractDiet> { 
    protected T diet; 
} 
public class CatFoodDiet extends AbstractDiet { 
    compute() { 
     // 
    } 
} 
public class Cat extends AbstractAnimal<CatFoodDiet> { 
    // use field in super which is type CatFoodDiet 
} 

但通常你會使用接口而不是抽象類的抽象類型。

1

最靈活的方式是隻需要子類來提供信息的:

public abstract class AbstractAnimal { 
    // Subclasses must provide a function that returns the diet 
    public abstract AbstractDiet getDiet(); 
} 

public class PetRock extends AbstractAnimal { 
    @Override 
    public AbstractDiet getDiet() { 
     return new SunlightDiet(); 
    } 
} 

如果你想強制某個特定的實現,這是一種常見的方式:

public abstract class AbstractAnimal { 
    private AbstractDiet diet; 

    // Provide a constructor that sets a diet 
    protected AbstractAnimal(AbstractDiet aDiet) { 
     if (null == aDiet) 
      throw new NullPointerException("Diet must be specified"); 
     diet = aDiet; 
} 

public class PetRock extends AbstractAnimal { 
    public PetRock() { 
     // Subclasses have to provide a diet to the superclass 
     super(new SunlightDiet()); 
    } 
}