我想知道是否有办法在不破坏封装的情况下执行此操作,我希望抽象类依赖于在实现子类中定义的参数。像这样:
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实现。
答案 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()中设置的值)