无法通过直接调用abstract
类的构造函数来创建对象。 abstract
类的构造函数只能从派生类中调用。因此,似乎对我来说,抽象类的构造函数必须是protected
或package-private(后者用于限制使用构造函数到包中的派生类的异常情况) 。然而,Java允许abstract
类的构造函数为public
。
在任何有用的情况下,将abstract
类的构造函数声明为public
,而不是protected
或package-private ?
这与问题“Abstract class constructor access modifier”完全重复:显然,可以将构造函数声明为public
;我想知道是否有任何良好的理由这样做。在我看来,没有。我看到C# has a similar peculiarity。
答案 0 :(得分:19)
java的答案是相同的:
对于抽象类,没有理由使用公共构造函数。我假设编译器没有抱怨的原因很简单,他们只是没有花时间来覆盖它,因为它是公共的还是受保护的并不重要。 (source)
您不能从直接子类以外的任何东西调用抽象类的构造函数。
因此,为抽象类的构造函数的访问修饰符添加一个特殊规则不会添加对该语言有用的东西。
一个看起来像这个规则的例外 - 如果抽象类只定义了默认构造函数,那么子类就不必实现构造函数:这是合法的:
public abstract class A {
public A() {}
}
public class B extends A {}
因此,我们可以通过调用B
来创建new B()
- 但请注意,我们仍然创建B
而不是A
。而且,A
中的构造函数是公共的还是受保护的并不重要。它不应该是私有的,但编译器会注意并抱怨...
实际上我们在B
上调用了一个“隐身”的公共默认构造函数,它只执行一个简单的super()
调用...
答案 1 :(得分:0)
可见性还会影响javadoc中显示的内容(如果选择它以排除某些可见性级别)。否则,这可能是抽象类的公共构造函数的用法。
如果没有提供构造函数,那么如果类是public,则默认构造函数是public。最简单的选择是允许它,而不是强制受保护的构造函数。
从这个意义上说,相反的问题可能会表明:他们为什么不强迫抽象类中的受保护构造函数?因为公共构造函数不会改变任何东西,所以它只需要时间并增加复杂性。
答案 2 :(得分:-7)
称我为异教徒,但是...我在抽象类中看到构造函数至少有一个用途。
即:指定构造函数参数的外观。
指定一个抽象构造函数(从而使类抽象)。派生类必须实现此构造函数及其特定签名才能失去抽象状态。
我认为没有其他方法可以指定强制构造函数签名(如果你这样做,请帮我解决)。
答案 3 :(得分:-8)
如果未在子类的构造函数中定义,则可以使用公共构造函数。 示例
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中实际使用它并且工作正常。