我知道我在这里问了一些严肃的问题......
我有一些课程Foo
和一个Bar
的课程Foo
。在Foo
中,我有一个构造函数,它将一组参数设置为其字段。派生诸如Bar
之类的类通常不需要修改它。现在我的IDE给了我“Foo中没有默认构造函数”。从谷歌搜索中看,这似乎是因为“构造函数不是继承的”。所以一切都很好,但是我现在如何在不重复每个派生类的构造函数的情况下使用它?我假设有一个更理智的方法?
答案 0 :(得分:61)
使用super
构造函数:
public Bar(int a, double b, ...) {
super(a, b, ...);
}
答案 1 :(得分:17)
所有这一切都很好,但是我现在如何在不重复每个派生类的构造函数的情况下使用它?
如果希望子类具有相同签名的构造函数,则需要复制构造函数签名。但是您不需要复制代码 - 您只需链接到超类构造函数:
public Bar(int x, int y) {
super(x, y);
// Any subclass-specific code
}
当然,如果您可以从不同的参数集中计算出超类参数,那很好。例如:
public Bar(int x) {
super(x, x * 2);
// Any subclass-specific code
}
你真的需要弄清楚构建一个Bar
- 所需的信息,应该指示你的构造函数。
如果这是一个问题,您可能会过度使用继承。如果不知道你的实际类是什么,很难肯定地说,但你应该看看使用组合而不是继承。这不是灵丹妙药,但它可以避免这种情况。
答案 2 :(得分:4)
不,没有更“理智”的方法。如果您的基类没有默认构造函数,那么您必须从所有子类中显式调用正确的构造函数。
请注意,这并不意味着子类需要具有与基类相同的完全构造函数。例如,这是完全有效的:
class Foo {
protected int a;
protected int b;
protected Foo(final int a, final int b) {
this.a = a;
this.b = b;
}
}
class Bar extends Foo {
protected Bar() {
super(0,0);
}
}
答案 3 :(得分:3)
这个问题解决了:
class Foo{
Foo(int a, int b){}
}
class Bar extends Foo{
//Here must be a constructor OR declare a constructor in Foo without parameters
Bar(){super(1,1)} //this is an example
}
其他解决方案是:
class Foo{
Foo(int a, int b){}
Foo(){}
}
class Bar extends Foo{
}
请记住,如果在 SuperClass (在本例中为Foo)中有一个带参数的构造函数,子类(在本例中为Bar)中的隐式构造函数,会隐式调用“超级()”(除非明确,否则必须是一个)。
答案 4 :(得分:0)
如果由于设计原因提供了默认构造函数,JVM将不会提供默认构造函数。您可以在Bar中使用相同的签名定义构造函数并调用super()。
public Bar(int x,int y) {
super(x,y);
}
答案 5 :(得分:0)
如果不需要参数和/或具有默认值,则可以定义默认构造函数(不带参数):
class Foo
{
public final int DEFAULT_A = 42;
protected int a;
protected int b;
public Foo(final int a, final int b)
{
this.a = a;
this.b = b;
}
// Is equal to new Foo(Foo.DEFAULT_A, 0);
public Foo()
{
this.a = this.DEFAULT_A;
}
}
class Bar extends Foo {}
class PiBar extends Bar
{
public final int DEFAULT_A = Math.PI;
}
答案 6 :(得分:0)
也可能发生此错误,因为您最后一次调用了超级构造函数。您可能必须将其移动为第一条语句:
public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
mFragmentList = fragmentList;
super(manager);
}
public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
super(manager); --> this should come first
mFragmentList = fragmentList;
}