Java 抽象类和非抽象类中的构造函数

Java 抽象类和非抽象类中的构造函数,java,Java,我有一个泛型容器类和一个扩展泛型容器的FIFOContainer类。尝试使用takeout()方法时出现问题。它不承认我在FIFOContainer ArrayList中保存了值。 我怀疑这与我如何定义构造函数有关,但我一生都不知道如何解决它 我想到的一个解决方案是在GenericContainer类中定义一个getter,并在FIFOContainer类中传递值,但我觉得不需要这样做 public abstract class GenericContainer implements IBag

我有一个泛型容器类和一个扩展泛型容器的FIFOContainer类。尝试使用takeout()方法时出现问题。它不承认我在FIFOContainer ArrayList中保存了值。 我怀疑这与我如何定义构造函数有关,但我一生都不知道如何解决它

我想到的一个解决方案是在GenericContainer类中定义一个getter,并在FIFOContainer类中传递值,但我觉得不需要这样做

public abstract class GenericContainer implements IBag {

    private ArrayList<ISurprise> container;

    public GenericContainer() {
        this.container = new ArrayList<ISurprise>();
    }

    @Override
    public void put(ISurprise newSurprise) {
        this.container.add(newSurprise);
    }

    @Override
    public void put(IBag bagOfSurprises) {
        while (!bagOfSurprises.isEmpty()) {
            System.out.println(bagOfSurprises.size());
            this.container.add(bagOfSurprises.takeout());
        }
    }

    @Override
    public boolean isEmpty() {
        if (this.container.size() > 0) {
            return false;
        }
        return true;
    }

    @Override
    public int size() {
        if (isEmpty() == false) {
            return this.container.size();
        }
        return -1;
    }

}

public class FIFOContainer extends GenericContainer {

    private ArrayList<ISurprise> FIFOcontainer;

    public FIFOContainer() {
        super();
        this.FIFOcontainer = new ArrayList<ISurprise>();        

    }

    public ISurprise takeout() {
        if (isEmpty() == false) {
            this.FIFOcontainer.remove(0);
            ISurprise aux = this.FIFOcontainer.get(0);
            return aux;
        }
        return null;
    }
}
公共抽象类GenericContainer实现IBag{
私有ArrayList容器;
公共通用容器(){
this.container=new ArrayList();
}
@凌驾
公开作废认沽权证(ISurprise newSurprise){
this.container.add(newSurprise);
}
@凌驾
公开作废认沽权(IBag BagofPrinces){
而(!bagofsurprices.isEmpty()){
System.out.println(bagofSurprices.size());
this.container.add(bagOfSurprises.takeout());
}
}
@凌驾
公共布尔值为空(){
if(this.container.size()>0){
返回false;
}
返回true;
}
@凌驾
公共整数大小(){
if(isEmpty()==false){
返回此.container.size();
}
返回-1;
}
}
公共类FIFOContainer扩展了GenericContainer{
私人ArrayList FIFOcontainer;
公共FIFOContainer(){
超级();
this.FIFOcontainer=新的ArrayList();
}
公共ISurprise外卖(){
if(isEmpty()==false){
此.FIFOcontainer.remove(0);
ISurprise aux=this.FIFOcontainer.get(0);
返回aux;
}
返回null;
}
}

您不应该在
FIFOContianer
中创建新的arraylist。您已经有了来自
GenericContainer
的列表
所以现在,当您调用
put
时,它会将项添加到父类中的
容器
列表中。调用
外卖
时,您正在访问在子类中创建的其他列表(
FIFOcontainer

只需卸下
FIFOcontainer
并继续使用
容器

public ISurprise外卖(){
if(isEmpty()==false){
此.container.remove(0);
ISurprise aux=this.container.get(0);
返回aux;
}
返回null;
}

问题是:字段不是poylmorphic(参见示例)

您的问题:基本上您的
isEmpty()
将在基类中使用容器,而另一个方法将在子类中使用容器

是的,你们班有两个容器

更好的方法是(例如)在基类GenericContainer中执行此操作:

protected abstract List<ISurprise> getContainer();
为了允许更多的自由度,该方法还可以有稍微不同的签名,例如
受保护的抽象集合
,以便在实际实现方面更加灵活

(提示:我最终确定了该方法,因为这是在抽象基类中定义的方法的全部思想:子类不会覆盖它们)


(还有额外的提示:尽量减少您编写的代码量。您不需要执行
someBool==true/false
,也不需要执行
getSize()==0
,因为该列表类已经为您提供了一个isEmpty()方法)

但是GenericContainer中的容器字段是私有的。如果没有getter,这将不起作用。当getter受到保护时,您应该将其更改为受保护的@BogdanBuzaianu,这样当然可以获得超类的私有字段。但正如我在回答中所写:这是错误的方式。如果子类允许访问“它们的”容器,我可能会更有意义。@GhostCat我同意您的答案是更好的,并且注意到它遵循开闭原则,而不是在FIFOcontainer类中重写isEmpty()方法,如果(getContainer().isEmpty()==false)则不会同样有效?@BogdanBuzaianu请仔细阅读:我的方法是:基类可以调用
getContainer()
来完成它的工作,子类将实现这一点。同样:当您已经有一个方法对该集合本身执行
boolean isEmpty()
,那么在该集合周围放置if语句并==false只不过是噪声。base.isEmpty()的结果就是:getContainer.getEmpty()。不需要if,不需要比较,不需要说==false,不需要第二次返回true。这就是我感到困惑的地方:我在GenericContainer类中定义抽象方法getContainer。我在FIFOContainer类中覆盖了它。但是我在GenericContainer isEmpty()中执行此操作:return getContainer.isEmpty();。既然该方法在子类中被重写,它应该如何工作?对不起,我真的很想理解,但是OOP对我来说是非常新的me@BogdanBuzaianu子类实现“getContainer()”。只有那个。基类实现isEmpty()。而且子类不涉及isEmpty()!这意味着我不再需要基类中的ArrayList字段,因为我可以始终调用getContainer()?您应该遵循Java命名约定:变量名和方法名都是用camelCase编写的。因此,
FIFOcontainer
违反了这些约定。另一个提示:您的size()方法,这真是荒谬。同样:if语句中的值为零。常规容器大小。。。是其容器的大小。您正在编写大量不必要的代码。更糟糕的是:它令人困惑,因此允许bug隐藏。as:任何java集合的大小都不能为-1。大小从0到任意值。它们不是消极的。
@Override
public final boolean isEmpty() {
    return getContainer().isEmpty();
}