抽象类的公共构造函数有充分的理由吗
无法通过直接调用抽象类的构造函数来创建对象。 抽象
类的构造函数只能从派生类中调用。因此,在我看来,抽象类的构造函数必须是受保护的或包私有的(后者用于限制在派生类中使用构造函数的不寻常情况)包)。然而,Java 允许抽象
类的构造函数是public
。
是否存在将抽象
类的构造函数声明为public
而不是protected有用的情况code> 还是包私有?
这与问题“抽象类构造函数访问修饰符”不太重复:显然您可以将构造函数声明为public
;我想知道是否有任何充分理由这样做。在我看来,没有。我发现 C# 也有类似的特性。
It is not possible to create an object by directly calling the constructor of an abstract
class. The constructor of an abstract
class can be called only from a derived class. It therefore seems to me that constructors of an abstract class must be either protected
or package-private (the latter for the unusual cases of restricting use of a constructor to derived classes within the package). Yet Java allows the constructor of an abstract
class to be public
.
Are there any circumstances in which it is useful to declare the constructor of an abstract
class to be public
, rather than protected
or package-private?
This is not quite a duplicate of the question "Abstract class constructor access modifier": clearly you can declare a constructor to be public
; I want to know whether there is ever any good reason to do so. It seems to me that there is not. I see that C# has a similar peculiarity.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于java来说答案是一样的:
您无法调用构造函数来自直接子类以外的任何抽象类。
因此,为抽象类的构造函数的访问修饰符添加特殊规则不会为该语言添加有用的内容。
有一点看起来像是此规则的例外 - 如果抽象类仅定义默认构造函数,则子类不必实现构造函数:这是合法的:
因此我们可以创建一个
B
通过调用new B()
- 但请注意,我们仍然创建一个B
而不是A
。而且,A 中的构造函数是公共的还是受保护的并不重要。它不应该是私有的,但编译器会注意到并抱怨......实际上我们在
B
上调用一个“不可见的”公共默认构造函数,它执行一个简单的super()
打电话...The answer is the same for java:
You can't call a constructor of an abstract class from anything other than a direct subclass.
So adding a special rule for access modifiers of constructors of abstract classes wouldn't add something useful to the language.
One thing that looks like an exception from this rule - if the abstract class only defines a default constructor, then the subclass does not have to implement a constructor: this is legal:
So we can create a
B
by callingnew B()
- but note, that we still create aB
and not anA
. And, again, it doesn't matter if the constructor inA
is public or protected. It just shouldn't be private, but the compiler will notice and complain...Actually we invoke an "invisible" public default constructor on
B
which does a simplesuper()
call...可见性还会影响 javadoc 中显示的内容(如果选择排除某些可见性级别)。否则并不重要,这可能是抽象类的公共构造函数的用法。
如果您未提供构造函数,则如果该类是公共的,则默认构造函数也是公共的。最简单的选择是允许这样做,而不是强制使用受保护的构造函数。
从这个意义上说,相反的问题可能会清楚地表明:为什么他们不在抽象类中强制使用受保护的构造函数?因为公共构造函数不会改变任何东西,所以它只会花费时间并增加复杂性。
The visibility also infuences what is shown in the javadoc (if it's selected to exclude certain visibility levels). As it doesn't matter otherwise, that could be a usage for a public constructor of an abstract class.
If you provide no constructor, then the default constructor is public if the class is public. Easiest option would be to allow that, rather than forcing protected constructors.
In that sense the reverse question may make it clear: why didn't they force protected constructors in abstract classes? Because public constructors won't change anything, so it would just take time and add complexity.
你可以称我为异教徒,但是……我看到构造函数在抽象类中至少有一种用途。
即:指定构造函数参数是什么样的。
指定一个抽象构造函数(从而使类抽象)。派生类必须使用其特定签名来实现此构造函数,以失去抽象状态。
我认为没有其他方法可以指定强制构造函数签名(如果您这样做,请帮助我)。
Call me a heretic, but ... I see at least one use for a constructor in an abstract class.
That is: to specify what the constructor parameters look like.
Specify an abstract constructor (thus making the class abstract). Derived classes have to implement this constructor with its specific signature to lose abstract status.
I see no other way to specify mandatory constructor signatures (help me out if you do).
如果没有在子类的构造函数中定义,则可以拥有公共构造函数。
例如
,如果没有定义构造函数,则将调用父类构造函数,如果它不是公共的,则它将不起作用。我认为使用工厂模式可以更优雅地完成此操作,但我在 PHP 实践中使用了它并且效果很好。
You can have a public constructor if you do not define in a constructor in the sub-class.
example
if no constructor is defined the parent class constructor will be called, if it is not public it will not work. This I think is more elegantly done with a factory pattern, but I used it in practice in PHP and it works fine.