Java最终抽象类

时间:2012-03-08 13:44:34

标签: java class abstract final

我有一个非常简单的问题:

我想要一个Java类,它提供了一个公共静态方法,它可以做一些事情。这仅用于封装目的(在一个单独的类中包含所有内容)...

此类既不应实例化,也不应扩展。这让我写道:

final abstract class MyClass {
   static void myMethod() {
      ...
   }
   ... // More private methods and fields...
}

(虽然我知道,这是禁止的。)

我也知道,我可以使这个类完全是final,并覆盖标准构造函数,同时将其设为私有。

但在我看来,这更像是一种“解决方法”,并且应该更有可能通过最终的抽象类来完成......

我讨厌变通方法。所以只是为了我自己的利益:还有另一种更好的方法吗?

9 个答案:

答案 0 :(得分:50)

比使用没有实例的enum简单得多。

public enum MyLib {;

   public static void myHelperMethod() { }
}

这个类是final的,显式没有实例和私有构造函数。

这是由编译器检测到的,而不是运行时错误。 (与抛出异常不同)

答案 1 :(得分:45)

参考:有效的Java第2版第4项“使用私有构造函数强制实现非实例化”

public final class MyClass { //final not required but clearly states intention
    //private default constructor ==> can't be instantiated
    //side effect: class is final because it can't be subclassed:
    //super() can't be called from subclasses
    private MyClass() {
        throw new AssertionError()
    }

    //...
    public static void doSomething() {}
}

答案 2 :(得分:6)

不,你应该做的是创建一个私有空构造函数,在它的主体中抛出异常。 Java是一种面向对象的语言,一个永远不会被实例化的类本身就是一种解决方法! :)

final class MyLib{
    private MyLib(){
        throw new IllegalStateException( "Do not instantiate this class." );
    }

    // static methods go here

}

答案 3 :(得分:4)

不,抽象类是要扩展的。使用私有构造函数,它不是一种解决方法 - 它是这样做的方法!

答案 4 :(得分:2)

将类的构造函数声明为private。这确保了不可实现性并阻止了子类化。

答案 5 :(得分:1)

assylias(所有Java版本)和Peter Lawrey(> = Java5)的建议是这种情况下的标准方法。

但是我想提醒你注意,防止静态实用程序类的扩展是一个非常最终的决定,当你发现在不同的项目中你有相关的功能而你可能会在以后困扰你。事实上,我想扩展它。

我建议如下:

public abstract MyClass {

    protected MyClass() {
    }

    abstract void noInstancesPlease();

    void myMethod() {
         ...
    }
    ... // More private methods and fields...

}

这是反对已建立的实践,因为它允许在需要时扩展类,它仍然可以防止意外实例化(甚至无法创建匿名子类实例而不会得到非常清晰的编译器错误)。

总是 pisses 我JDK的实用程序类(例如java.util.Arrays)实际上是最终的。如果你想拥有自己的Arrays类和方法来比较,你就不能,你必须创建一个单独的类。这将分发(IMO)所属的功能,并且应该通过一个类提供。这使您无法使用分布式实用方法,或者您必须将每个方法复制到您自己的类中。

我建议永远不要让这样的实用程序类最终。在我看来,这些优点并没有减轻它们的劣势。

答案 6 :(得分:0)

您不能将课程标记为抽象和最终。他们几乎相反 含义。抽象类必须是子类,而最终类不能是子类 子类。如果您看到用于类或方法声明的抽象和最终修饰符的组合,则代码将无法编译。

答案 7 :(得分:-1)

这是一个非常简单的解释,简单的英语。抽象类无法实例化,只能扩展。最终的类不能扩展。现在如果你创建一个抽象类作为最终类,你怎么认为&#39我将永远使用那个课程,实际上,首先是把自己置于这样一个陷阱的理由是什么?

答案 8 :(得分:-2)

Check this Reference Site..

不可能。没有被继承的抽象类没有用,因此会导致编译时错误。

谢谢..