代码之家  ›  专栏  ›  技术社区  ›  James McMahon

如何从Java中抽象出一个抽象的基元?

  •  11
  • James McMahon  · 技术社区  · 15 年前

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

    如果我将公共功能放在继承自公共祖先的基类中,我会得到一个没有意义的类来实例化,因此我将其抽象化。此外,由于这些类都用作单例,它们都应该有一个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;
        }
    }
    

    我可以把基类中的非法行去掉,然后处理掉。但是我如何表达基地的每个孩子 必须 有这些方法吗?

    4 回复  |  直到 15 年前
        1
  •  14
  •   Aaron Digulla    15 年前

    这在Java中是不可能的。存在 static 方法不能强制执行;两者都不能通过 abstract 也不使用 interface .

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

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

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

        2
  •  3
  •   Paul Morie    15 年前

    处理向类中添加单例语义的一种常见方法是在包装类中实现单例功能,这可能不方便正确地添加语义。例如:

    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 .

        3
  •  2
  •   Matthew Murdoch    15 年前

    你不能说孩子的课程有特定的 静止的 方法。

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

        4
  •  1
  •   Bill K    15 年前

    为什么不一路走,让你的工厂(在基类中)传入一个参数,指示你希望它返回哪个子类。这样做有很多优点,也没有什么缺点。

    因为静态方法处理继承的方式与处理普通方法的方式不完全相同,所以您尝试这样做的方式没有太多意义。