[英]Abstract class get parameter from implementing subclass?
I'm wondering if there is way to do this without breaking encapsulation, I want the abstract class to rely on parameters defined in the implementing subclass. 我想知道是否存在不破坏封装的方法,我希望抽象类依赖于实现子类中定义的参数。 Like so:
像这样:
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;
}
}
Is this ugly? 这很丑吗? Is there a better way?
有没有更好的办法? And perhaps more importantly, is this even a good idea?
也许更重要的是,这是否是个好主意?
EDIT: 编辑:
The classes are created in the context of a framework, so the default parameter-less constructor is always the one called (in fact, the Parent class extends another class). 这些类是在框架的上下文中创建的,因此默认的无参数构造函数始终是被调用的构造函数(实际上,Parent类扩展了另一个类)。 The size parameter is just used for illustration purposes and I don't plan on using it for a List implementation.
size参数仅用于说明目的,我不打算将其用于List实现。
No, is not ugly. 不,不难看。 This pattern is named "template method".
该模式称为“模板方法”。 But typically it is more useful when the method is not a simple getter but something that implement business logic.
但是通常,如果该方法不是简单的获取方法,而是实现业务逻辑的方法,则它会更有用。
In your case other solution is to define protected constructor in Parent class and call it with relevant parameter from child: 在您的情况下,另一种解决方案是在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);
}
}
If the constructor is the only place you use getSize()
, just require it as a constructor parameter. 如果构造函数是您使用
getSize()
的唯一位置,则只需将其作为构造函数参数即可。
But more importantly, why do you care about size? 但更重要的是,为什么要关心尺寸? Unless you know there's a problem, just use the default size like everybody else:
除非您知道有问题,否则像其他所有人一样使用默认大小:
public abstract class Parent {
private List<String> someList = new ArrayList<String>();
// use default constructor
}
The pattern is not ugly, except when you try to use it in the constructor. 该模式并不难看,除非您尝试在构造函数中使用它。 It allows you to modify Child in a way that results are unexpected.
它允许您以意外的方式修改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;
}
}
If you now create an instance of Child it would actually throw an exception because a negative capacity is not allowed. 如果现在创建Child的实例,则实际上将引发异常,因为不允许负容量。 You should realize that the properties of a class are only initialized after the parent constructor has finished.
您应该意识到,仅在父构造函数完成后才初始化类的属性。 (And if a property is set using the Parent constructor and has a default value defined in Child, it will happily overwrite the value you just set in Parent() )
(如果属性是使用Parent构造函数设置的,并且在Child中定义了默认值,那么它将很乐意覆盖您刚刚在Parent()中设置的值)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.