2014-04-08 90 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()); 
    } 
}