为什么构造函数在Java中不能是final,static或abstract?
例如,你能解释一下为什么这是无效的吗?
public class K {
abstract public K() {
// ...
}
}
答案 0 :(得分:152)
当您将方法设置为final
时,它意味着:“我不希望任何类覆盖它。”但是根据Java语言规范:
JLS 8.8 - “构造函数声明不是成员。它们永远不会被继承,因此不会被隐藏或覆盖。”
当您将方法设置为abstract
时,它意味着:“此方法没有正文,它应该在子类中实现。”但构造函数是隐式调用的当使用new
关键字时,它不能缺少正文。
当您将方法设置为static
时,它意味着:“此方法属于类,而不是特定对象。”但隐式调用构造函数来初始化对象,因此拥有静态构造函数没有任何意义。
答案 1 :(得分:39)
这个问题确实是你想要构造函数为static or abstract or final
的原因。
构造函数不是继承的,所以不能覆盖,所以使用是什么 拥有最终的构造函数
当类的实例是时,将自动调用构造函数 创建后,它可以访问该类的实例字段。会是什么 使用静态构造函数。
无法覆盖构造函数,因此您将使用抽象做什么 构造
答案 2 :(得分:14)
Java构造函数隐式 final,其语义的静态/非静态方面是隐式 1 ,它是无意义的,以使Java构造函数成为抽象的。
这意味着final
和static
修饰符将是多余的,abstract
关键字根本没有意义。
自然地,Java设计者在任何方面都没有看到在构造函数上允许冗余和/或无意义的访问修饰符......所以Java语法不允许这些。
除此之外:遗憾的是,他们没有对接口方法进行相同的设计调用,其中public
和abstract
修饰符也是多余的,但无论如何都是允许的。也许这有一些(古老的)历史原因。但无论如何,如果没有渲染(可能)数以百万计的现有Java程序无法编译,它就无法修复。
1 - 实际上,构造函数具有静态和非静态语义的混合。您不能“调用”实例上的构造函数,它们不会被继承或覆盖。这类似于静态方法的工作方式。另一方面,构造函数的主体可以引用this
,并调用实例方法......就像实例方法一样。然后是构造函数链接,这对于构造函数是唯一的。但真正的一点是,这些语义是固定的,没有必要允许冗余且可能令人困惑的static
修饰符。
答案 3 :(得分:9)
public
构造函数:可以在任何地方创建对象。
默认构造函数:只能在同一个包中创建对象。
protected
构造函数:只有当对象是子类时,才可以通过包外的类创建对象。
private
构造函数:只能在类中创建对象(例如,在实现单例时)。
static
,final
和abstract
关键字对构造函数没有意义,因为:
static
成员属于某个类,但需要构造函数来创建对象。
abstract
类是部分实现的类,它包含要在子类中实现的抽象方法。
final
限制修改:变量变为常量,方法无法覆盖,类无法继承。
答案 4 :(得分:6)
最终:因为无论如何都无法覆盖/扩展构造函数。你可以扩展一个类(以防止你使它成为最终的)或覆盖一个方法(以防止你使它成为最终的),但是对于构造函数没有这样的东西。
静态:如果你看一下执行一个构造函数是不是静态的(它可以访问实例字段),如果你看一下调用者那么它是(有点)静态的(你没有调用它)有一个实例。很难想象构造函数是完全静态的还是不是静态的,并且在这两个东西之间没有语义分离,用修饰符来区分它们是没有意义的。
摘要:摘要只有在覆盖/扩展的情况下才有意义,所以与'final'相同的参数适用
答案 5 :(得分:6)
不能将构造函数声明为final。您的编译器将始终给出“modifier final not allowed”类型的错误 最后,当应用于方法时,意味着不能在子类中重写该方法。 构造函数不是普通的方法。 (适用不同规则) 此外,构造函数永远不会继承。所以宣布最终决定没有任何意义。
答案 6 :(得分:3)
答案 7 :(得分:2)
JLS section 8提到了这一点。
构造函数(§8.8)类似于方法,但无法调用 直接通过方法调用;它们用于初始化新类 实例。与方法一样,它们可能会过载(§8.8.8)。
但每个人所说的构造函数不是常规方法。它们无法进行比较。
答案 8 :(得分:1)
为什么构造函数不能是静态的,最终在上面的答案中定义得很好。
摘要:“摘要”意味着没有实现。它只能通过继承来实现。因此,当我们扩展某个类时,除了“构造函数”之外,所有父类成员都在子类(子类)中继承。那么,让我们假设,你有一些如何管理声明构造函数“Abstract”,而不是如何在子类中给出它的实现,当构造函数没有在子类中继承时?
这就是构造函数不可能的原因 摘要。
答案 9 :(得分:0)
让我们先看看 最终公开K(){
*在修饰符final之上是限制因为如果它最终然后在某些情况下,在某些其他类或同一类只有我们将覆盖它以便不会发生在这里而不是最终 例如:
we want public void(int i,String name){
//this code not allowed
让静态,静态itz全部关于类级别,但我们使用' new'创建基于对象的构造函数。关键字so ,,,,,, thatsall
抽象itz最糟糕的是这里不是因为没有任何抽象方法或任何声明的方法
答案 10 :(得分:0)
不幸的是,在PHP中,编译器对于abstract
和final
构造函数都不会引起任何问题。
<?php
abstract class AbstractClass
{
public abstract function __construct();
}
class NormalClass
{
public final function __construct() {
echo "Final constructor in a normal class!";
}
}
在PHP中,static
的构造函数是不允许的,并且会引发fatal
异常。
在AbstractClass
中显然可以将构造函数声明为抽象加未实现,也可以将其声明为(final
,{{1 }},public
,private
)以及一个函数主体。
PHP上的其他一些相关事实:
protected
。__construct()
可以声明为__construct()
,abstract
,final
,public
和private
!此代码经过测试,在5.6到7.4的PHP版本中都适用!