【问题标题】:Why can't constructors be final, static, or abstract?为什么构造函数不能是最终的、静态的或抽象的?
【发布时间】:2012-02-28 06:35:00
【问题描述】:

为什么构造函数在 Java 中不能是最终的、静态的或抽象的?

例如,您能向我解释一下为什么这是无效的吗?

public class K {

    abstract public K() {
        // ...
    }
}

【问题讨论】:

  • 考虑每个关键字对其他方法的作用。有时它在构造函数的上下文中没有意义,有时它已经被暗示了。
  • 为什么需要静态构造函数?这个问题听起来像是一道作业题。

标签: java syntax constructor


【解决方案1】:

当您将方法设置为final 时,这意味着:“我不希望任何类覆盖它。” 但根据 Java 语言规范:

JLS 8.8 - “构造函数声明不是成员。它们永远不会被继承,因此不会被隐藏或覆盖。”

当您将方法设置为abstract 时,这意味着:“此方法没有主体,它应该在子类中实现。” 但是当使用new 关键字,因此不能缺少正文。

当你设置一个方法为static时,它的意思是:“这个方法属于类,不是特定的对象。”但是构造函数被隐式调用来初始化一个对象,所以有没有静态构造函数。

【讨论】:

  • 什么是 JLS?如果您在第一次使用此首字母缩写词时解释它可能对某些人有用。没关系,我把这个给你了。
  • JLS 是 Java 语言规范的首字母缩写
  • 今天我在技术电话屏幕上被问到这个问题,我不知道,但听起来好像我不能把 final 放在构造函数声明之前。
  • 在接口中提供“抽象”构造函数签名可能很有用,这意味着:“任何实现此接口的类都必须提供具有此签名的构造函数”。目前,接口可以非正式地记录实现类应该创建具有特定签名的构造函数,但 Java 中没有设计模式可以强制或检查这一点。
【解决方案2】:

问题真的是为什么你希望构造函数是static or abstract or final

构造函数不是继承的所以不能被覆盖所以有什么用 拥有最终构造函数

构造函数在类的实例被调用时自动调用 创建后,它可以访问类的实例字段。会是什么 使用静态构造函数。

构造函数不能被覆盖,所以你将如何处理抽象 构造函数。

【讨论】:

    【解决方案3】:

    Java 构造函数是隐式 final,其语义的静态/非静态方面是隐式1,它是没有意义 Java 构造函数是抽象的。

    这意味着finalstatic 修饰符将是多余的,而abstract 关键字将毫无意义。

    当然,Java 设计者在任何时候都没有看到允许在构造函数上使用冗余和/或无意义的访问修饰符......所以这些在 Java 语法中是不允许的。

    旁白:很遗憾他们没有对接口方法进行相同的设计调用,其中publicabstract 修饰符也是多余的,但无论如何都是允许的。也许这有一些(古老的)历史原因。但无论哪种方式,如果不使(可能)数百万个现有的 Java 程序无法编译,就无法修复它。


    1 - 实际上,构造函数混合了静态和非静态语义。您不能在实例上“调用”构造函数,并且它们不是继承的,也不是可覆盖的。这类似于静态方法的工作方式。另一方面,构造函数的主体可以引用this,并像实例方法一样调用实例方法。然后是构造函数链接,这是构造函数独有的。但真正的重点是这些语义是固定的,没有必要允许多余且可能令人困惑的static 修饰符。

    【讨论】:

      【解决方案4】:
      • public构造函数:对象可以在任何地方创建。

      • 默认构造函数:对象只能在同一个包中创建。

      • protected构造函数:对象只能由包外的类创建,前提是它是子类。

      • private构造函数:对象只能在类内部创建(例如,在实现单例时)。

      staticfinalabstract 关键字对于构造函数没有意义,因为:

      • static成员属于一个类,但是创建对象需要构造函数。

      • abstract 类是部分实现的类,其中包含要在子类中实现的抽象方法。

      • final 限制修改:变量变为常量,方法不能被覆盖,类不能被继承。

      【讨论】:

        【解决方案5】:

        Final:因为无论如何您都无法覆盖/扩展构造函数。您可以扩展一个类(以防止您将其设为 final)或覆盖一个方法(以防止您将其设为 final),但构造函数没有这样的事情。

        静态:如果您查看构造函数的执行,它不是静态的(它可以访问实例字段),如果您查看调用方,它是(某种)静态的(您调用它时没有有一个实例。很难想象一个构造函数是完全静态的还是非静态的,并且如果没有在这两者之间进行语义分离,用修饰符来区分它们是没有意义的。

        Abstract:Abstract 只有在存在覆盖/扩展时才有意义,因此与“final”相同的参数适用

        【讨论】:

          【解决方案6】:

          任何构造函数都不能被声明为 final。您的编译器将始终给出“不允许修饰符最终”类型的错误 当应用于方法时,final 意味着该方法不能在子类中被覆盖。 构造函数不是普通的方法。 (适用不同的规则) 此外,构造函数永远不会被继承。所以宣布它是最终的没有意义。

          【讨论】:

            【解决方案7】:
            1. 构造函数不是普通的方法。 (适用不同的规则)
            2. 此外,构造函数永远不会被继承。所以宣布它是最终的没有任何意义。 任何构造函数都不能被声明为最终的。你的编译器总是会给出“modifer final not allowed”类型的错误
            3. 查看 JLS 第 8.8.3 节(JLS 和 API 文档应该是您的一些主要信息来源)。

            【讨论】:

              【解决方案8】:

              JLS section 8 提到了这一点。

              构造函数(第 8.8 节)类似于方法,但不能被调用 直接通过方法调用;它们用于初始化新类 实例。与方法一样,它们可能会被重载(第 8.8.8 节)。

              但是每个说的构造函数不是常规方法。它们不能这样比较。

              【讨论】:

                【解决方案9】:

                为什么构造函数不能是 static 和 final 在上面的答案中得到了很好的定义。

                Abstract:“Abstract”意味着没有实现。它只能通过继承来实现。因此,当我们扩展某个类时,除了“构造函数”之外,所有父类成员都在子类(子类)中继承。所以,让我们假设,当构造函数没有在子类中继承时,你如何设法声明构造函数“Abstract”,而不是如何在子类中给出它的实现?

                这就是为什么构造函数不能 抽象的 。

                【讨论】:

                  【解决方案10】:

                  让我们先看看 最终公开 K(){

                  * 在修饰符 final 之上是限制,因为如果它是最终的,那么在某些情况下,只有在某个其他类或同一个类中,我们将覆盖它,这样就不会在这里发生,大约不是最终的 例如:

                  we want public void(int i,String name){
                  //this code not allowed
                  

                  let static,, static itz 都是关于类级别的,但是我们使用'new'关键字创建基于对象的构造函数,所以,,,,,,就是这样

                  abstract itz 最糟糕的是这里不是因为没有任何抽象方法或任何声明的方法

                  【讨论】:

                    【解决方案11】:

                    不幸的是,在 PHP 中,编译器不会对 abstractfinal 构造函数产生任何问题。

                    <?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 中,显然构造函数可以声明为抽象加未实现,也可以声明为介于(finalpublicprivate , protected) 加上一个函数体

                    关于 PHP 的一些其他相关事实:

                    1. 在 PHP 中具有多个构造函数 __construct() 是不可能的。
                    2. 在 PHP 中,构造函数 __construct() 可以声明为 abstractfinalpublicprivateprotected

                    此代码经过测试,适用于 5.6 到 7.4 的 PHP 版本!

                    【讨论】:

                      猜你喜欢
                      • 2014-01-24
                      • 1970-01-01
                      • 2011-08-13
                      • 2017-06-04
                      • 2010-09-27
                      • 2011-12-08
                      • 1970-01-01
                      • 2010-10-01
                      • 2016-12-17
                      相关资源
                      最近更新 更多