0

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

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 实现。

4

3 回答 3

4

不,不丑。这种模式被命名为“模板方法”。但通常,当方法不是简单的 getter 而是实现业务逻辑的东西时,它会更有用。

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

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);
    }
}
于 2012-09-23T09:42:08.033 回答
2

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

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

public abstract class Parent {

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

    // use default constructor    
}
于 2012-09-23T09:39:27.440 回答
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() 中设置的值)

于 2012-09-23T14:29:06.173 回答