我怎么能有一个';是从Java中的抽象基类型派生的吗?

我怎么能有一个';是从Java中的抽象基类型派生的吗?,java,inheritance,singleton,Java,Inheritance,Singleton,我有一些类被用作单例。它们共享一些基本功能,并从一个库中扩展了相同的祖先,而这个库通常不作为单例使用 如果我把公共功能放在一个从公共祖先继承的基类中,我会得到一个实例化没有意义的类,所以我把它抽象了。另外,由于这些类都作为单例使用,它们都应该有一个init()和一个getInstance()方法,这两个方法都是静态的。当然,所有的建设者都是非公共的 现在,由于static是抽象方法的非法修饰符,下面的方法不起作用,尽管这正是我想要的: class Base extends LibraryClas

我有一些类被用作单例。它们共享一些基本功能,并从一个库中扩展了相同的祖先,而这个库通常不作为单例使用

如果我把公共功能放在一个从公共祖先继承的基类中,我会得到一个实例化没有意义的类,所以我把它抽象了。另外,由于这些类都作为单例使用,它们都应该有一个init()和一个getInstance()方法,这两个方法都是静态的。当然,所有的建设者都是非公共的

现在,由于
static
是抽象方法的非法修饰符,下面的方法不起作用,尽管这正是我想要的:

class Base extends LibraryClass {
    protected Base() {
        // ... constructor
    }

    // ... common methods

    // ILLEGAL!
    public static abstract void init();
    public static abstract <T extends Base>T getInstance();
}

class A extends Base {
    private static A _INSTANCE;

    private A() {
        super();
    }

    public static void init() {
        _INSTANCE = new A();
    }

    public static A getInstance() {
        return _INSTANCE;
    }
}
类库扩展了LibraryClass{
保护基(){
//…构造器
}
//…常用方法
//违法!
公共静态抽象void init();
公共静态抽象T getInstance();
}
A类扩展基础{
私有静态A_实例;
私人A(){
超级();
}
公共静态void init(){
_实例=新的A();
}
publicstaticagetinstance(){
返回_实例;
}
}

我可以省略基类中的非法行,然后处理它。但是我如何表示Base的每个子类都必须有这些方法呢?

您不能表示子类有特定的静态方法


事实上,不需要这样做,因为静态方法只会直接在子类上调用(
A.init()
A.getInstance()
,在您的示例中),并且永远不会通过引用基类(即静态方法不支持多态性)。

这在Java中是不可能的。无法强制执行
静态
方法的存在;既不是通过
抽象
也不是通过使用
接口

我的解决方案是在某种程度上使用IoC:我为单例创建了一个工厂类。这会把单身汉保存在地图上。关键是课堂。这样,我可以说:

A singleton = Factory.create (A.class);

这种设计的主要优点是:我可以创建一个
Factory.replace()
方法,在这个方法中,测试用例可以覆盖单例。

为什么不尽全力让工厂(在基类中)传入一个参数,指示希望它返回的子类。这样做有很多好处,也没有什么坏处


您尝试这样做的方式没有多大意义,因为静态方法处理继承的方式与普通方法不太一样。

处理向类添加单例语义的常见方法是在包装器中实现单例功能,对于此类,正确添加语义可能会带来不便班级。例如:

public class UsefulThing {

}

public final class SingletonOfUsefulThing {
    private static UsefulThing instance;

    private SingletonOfUsefulThing() {}

    public UsefulThing getInstance() {
        if (instance == null) {
            instance = new UsefulThing(); 
        }

        return instance;
    }
}

这允许您为类提供一些主要的单例好处,而不会产生在类中实现单例语义直接迫使您处理的一些后果,并允许您更改作为单例公开的类的特定类型(例如,通过使用工厂来创建实例,而不是
new

为什么我们需要Singleton,即使Java中已经有Static或Final?迫使我们采用“Singleton”而不是“Static,Final”的主要原因是什么?虽然要实现单例,我们使用静态。我无法理解这个谜题。请转达您的意见。静态最终值适用于急切创建的常量。单例通常是惰性创建的(仅在需要时)。此外,静态最终值不允许替换“常量”因此,它们使测试变得困难甚至不可能。我想您的
getInstance()
方法也应该是
static