提问人:Raedwald 提问时间:1/25/2011 最后编辑:CommunityRaedwald 更新时间:4/2/2020 访问量:10451
抽象类的公共构造函数是否有充分的理由
Are there good reasons for a public constructor of an abstract class
问:
无法通过直接调用类的构造函数来创建对象。类的构造函数只能从派生类调用。因此,在我看来,抽象类的构造函数必须是包私有的或包私有的(后者用于将构造函数的使用限制为包中的派生类的不寻常情况)。然而,Java 允许类的构造函数是 .abstract
abstract
protected
abstract
public
在哪些情况下,将类的构造函数声明为 ,而不是 或 package-private 是有用的?abstract
public
protected
这与“抽象类构造函数访问修饰符”的问题并不完全重复:显然,您可以声明构造函数为 ;我想知道是否有任何充分的理由这样做。在我看来,没有。我看到 C# 具有类似的特性。public
答:
对于java来说,答案是一样的:
没有理由为抽象类使用公共构造函数。我认为编译器不抱怨的原因很简单,他们只是没有花时间覆盖它,因为它是公开的还是受保护的并不重要。(来源)
不能从直接子类以外的任何内容调用抽象类的构造函数。
因此,为抽象类构造函数的访问修饰符添加特殊规则不会为语言添加有用的东西。
有一件事看起来像是这条规则的例外 - 如果抽象类只定义一个默认构造函数,那么子类就不必实现构造函数:这是合法的:
public abstract class A {
public A() {}
}
public class B extends A {}
因此,我们可以通过调用来创建一个 - 但请注意,我们仍然创建一个而不是一个 .而且,同样,构造函数是公共的还是受保护的并不重要。它不应该是私有的,但编译器会注意到并抱怨......B
new B()
B
A
A
实际上,我们调用了一个“不可见”的公共默认构造函数,在该构造函数上执行简单的调用......B
super()
如果未在子类的构造函数中定义,则可以具有公共构造函数。 例
abstract class Animal {
String name;
public void Animal(String name) {
this.name = name;
}
}
class Cat extends Animal{
public String sayMayName() {
return this.name;
}
}
myCat = new Cat("tester");
name = myCat.sayMyName();
如果未定义构造函数,则将调用父类构造函数,如果它不是公共的,则将不起作用。我认为这在工厂模式中更优雅地完成,但我在 PHP 中在实践中使用它并且工作正常。
评论
Animal
void
Cat
Animal
public void Animal(String name)
称我为异教徒,但是......我看到抽象类中构造函数至少有一种用途。
即:指定构造函数参数的样子。
指定一个抽象构造函数(从而使类抽象)。派生类必须使用其特定签名实现此构造函数才能失去抽象状态。
我没有看到其他方法可以指定强制性构造函数签名(如果您这样做,请帮助我)。
评论
protected
super
super
abstract
可见性也会影响 javadoc 中显示的内容(如果选择它以排除某些可见性级别)。否则没关系,这可能是抽象类的公共构造函数的用法。
如果未提供构造函数,则默认构造函数为 public(如果类是 public)。最简单的选择是允许这样做,而不是强制受保护的构造函数。
从这个意义上说,相反的问题可以清楚地表明:为什么他们不在抽象类中强制使用受保护的构造函数?因为公共构造函数不会改变任何东西,所以它只会花费时间并增加复杂性。
评论
private