【问题标题】:Why can't a Java class be both abstract and final为什么 Java 类不能既是抽象类又是最终类
【发布时间】:2013-10-01 07:26:11
【问题描述】:

假设我有一个只包含静态方法和变量的实用程序类。例如:

public abstract final class StringUtils
{
    public static final String NEW_LINE = System.getProperty("line.separator");

    public static boolean isNotNullOrSpace(final String string)
    {
        return !(string == null || string.length() < 1 || string.trim().length() < 1);
    }
}

在这种情况下,将类设为抽象类和最终类是有意义的。抽象,因为创建此类的对象将毫无用处,因为所有方法都可以静态访问。最终,因为派生类不能从此类继承任何东西,因为它没有任何非静态成员。

C# 允许对此类类进行 static 修饰符。为什么 Java 不支持这个?

【问题讨论】:

  • 因为语言规范不同??然后是true
  • 谢谢巴特。您提供了正确的答案。我可以有一个带有私有构造函数的最终类。
  • 您已经混淆了final 的含义; final 相当于 C# 的 sealed,而不是 static
  • public final abstract class ChuckNorris extends ChuckNorris {}

标签: c# java static abstract-class final


【解决方案1】:

这是不可能的,因为 Java 语言规范规定:

声明一个抽象类类型是一个编译时错误,这样 不可能创建一个子类来实现它的所有 抽象方法[1]

除此之外,抽象最终类不合逻辑并没有内在的原因 - abstract 这个词通常用于与 concrete 形成对比,表示没有直接的一个类型的实例可能存在。

这与抽象方法不能具有私有访问修饰符的原因相同。

【讨论】:

    【解决方案2】:

    final 类无法扩展,abstract需要扩展才能被实例化。因此,final abstract 类将是一个逻辑矛盾。

    如果你的类只有static 方法,也许你应该只使用hide 它的构造函数,将其定义为private。-

    private StringUtils() {
    }
    

    【讨论】:

    • abstract 不需要被继承。只是无法实例化它。
    • 我知道这是面向对象语言的基本思想。但在我的例子中没有矛盾。我不想扩展或实例化我的类。
    • 嗯,就我而言,当您添加一些抽象方法时,抽象类是有意义的。如果您不希望您的类被实例化,您应该考虑将其默认构造函数定义为私有。
    • 或者,如果将类设置为 abstract 和 final 的唯一需要是没有人可以覆盖您的方法实现,您可以尝试将该方法单独标记为 final。
    • 请详细说明为什么一个类既不能实例化(它是抽象的)也不能扩展(它是最终的)是矛盾的。 Java 不允许在类上使用关键字同时声明两者,这不是事实!通过使用私有构造函数和规则来解决这个问题仍然并不少见。
    【解决方案3】:

    除了主观性之外没有其他原因,但您可以通过以下方式实现相同的目标 使您的类抽象并使您的所有方法成为最终方法。喜欢:

    public abstract class MyClass {
        …
        public final static void myMethod1() {
            …
        }
    
        public final static void myMethod2() {
            …
        }
    }
    

    如果您尝试实例化 MyClass 的对象,编译器将检查并给出错误,并且当任何子类扩展 MyClass 时,也无法覆盖最终方法

    【讨论】:

      【解决方案4】:

      当我们将一个类声明为抽象时,它不能被实例化。当我们将一个类声明为 final 时,它不能被继承。要实现抽象中的方法,需要继承 Class。但是如果我们将一个类声明为 final,则该类不能被继承。因此,我们不能将一个类声明为 abstractfinal

      【讨论】:

        【解决方案5】:

        由于某些原因,我们不能在抽象类中使用 final 关键字。

        1. 如果我们定义 abstract final 那么我们就不能扩展它。
        2. 抽象类意味着被其他一些类继承并提供非具体方法的实现。
        3. 如果我们将抽象类定义为最终类,它会给出编译时错误..

        【讨论】:

          【解决方案6】:

          一个方法永远不能同时被标记为abstract和final,或两者兼有 抽象和私密。想一想——必须实现抽象方法 (本质上意味着被子类覆盖)而 final 和 private 方法永远不能被子类覆盖。或者换一种说法,一个 抽象指定意味着超类不知道如何 子类应该在该方法中运行,而最终指定意味着 超类知道所有子类如何(无论离 它们可能是继承树)应该在该方法中表现。抽象和 final修饰符实际上是相反的。因为私有方法甚至不能 被子类看到(更不用说继承了),它们也不能被覆盖,所以它们也是 不能标记为摘要。

          【讨论】:

          • 问题是指最终的抽象类而不是方法
          【解决方案7】:

          在Java中不能创建抽象类的实例,我们只能有抽象类类型的引用。因此,如果我们将抽象类设为 final,那么我们将无法扩展它。 abstract 和 final 是互斥的概念。 这就是为什么当你尝试在 Java 中创建一个抽象类时,Java 编译器会抛出编译时错误

          【讨论】: