抽象类从实现子类获取参数?

时间:2012-09-23 09:35:41

标签: java

我想知道是否有办法在不破坏封装的情况下执行此操作,我希望抽象类依赖于在实现子类中定义的参数。像这样:

public abstract class Parent {

    private int size;
    private List<String> someList;

    public Parent() {
        size = getSize();
        someList = new ArrayList<String>(size);
    }

    public abstract int getSize();

}

public class Child extends Parent {

    @Override
    public int getSize() {
        return 5;
    }

}
这是丑陋的吗?有没有更好的办法?也许更重要的是,这是一个好主意吗?

修改

类是在框架的上下文中创建的,因此默认的无参数构造函数始终是调用的(实际上,Parent类扩展了另一个类)。 size参数仅用于说明目的,我不打算将其用于List实现。

3 个答案:

答案 0 :(得分:4)

不,不难看。此模式名为“模板方法”。但是,当方法不是简单的getter而是实现业务逻辑的东西时,它通常更有用。

在你的情况下,其他解决方案是在Parent类中定义受保护的构造函数,并使用child中的相关参数调用它:

public abstract class Parent {

    private int size;
    private List<String> someList;

    protected Parent(int size) {
        this.size = size;
        someList = new ArrayList<String>(size);
    }

    public int getSize() {
        return size;
    }

}

public class Child extends Parent {
    public Child() {
        super(5);
    }
}

答案 1 :(得分:2)

如果构造函数是您使用getSize()的唯一位置,则只需将其作为构造函数参数。

但更重要的是,你为什么要关心体型?除非您知道存在问题,否则请像其他人一样使用默认大小:

public abstract class Parent {

    private List<String> someList = new ArrayList<String>();

    // use default constructor    
}

答案 2 :(得分:1)

除非您尝试在构造函数中使用它,否则该模式并不难看。它允许您以结果意外的方式修改Child。

public class Child extends Parent {

    private int mySize = 5;

    @Override
    public int getSize() {
        // The -1 is only to help clarify what happens
        return mySize - 1;
    }

}

如果您现在创建Child的实例,它实际上会抛出异常,因为不允许负容量。您应该意识到类的属性仅在父构造函数完成后初始化。 (如果使用Parent构造函数设置属性并且在Child中定义了默认值,它将很乐意覆盖您在Parent()中设置的值)