如何允许第三方扩展我的java库中的类

时间:2015-05-15 19:02:12

标签: java inheritance instantiation

我在java中有一个父类,并且定义了一些行为

public class ParentClass {
    public ParentClass() {
        //Do some instantiation
    }

    public void doWork() {
       //Do some behavior defined by the parent class
    }
}

现在我的项目中有一些其他类使用它。让我们说它用在主

public class Main {

    public static void main(String [] args) {
        ParentClass parent = new ParentClass();
        parent.doWork();
    }

}

现在让我们说我的项目被设置为一个库供其他开发人员使用。我希望他们能够扩展ParentClass并根据自己的喜好覆盖doWork()方法。如果开发人员无法更改Main类,我如何确保在main()而不是ParentClass中实例化ChildClass?

ChildClass的示例

public class ChildClass extends ParentClass {
    public ChildClass() {
        super();
        //Do some more instantiation
    }

    @Override
    public void doWork() {
       super.doWork();
       //Do some more behavior in child class
    }
}

5 个答案:

答案 0 :(得分:2)

这取决于你想要实现的目标,如果你的库打算被另一个第三方使用,那么很可能你的主要方法将无关紧要,因为你的JAR包将捆绑在他自己的JAR中,这只会允许一个主要的班级;他的。

这种方法可能需要你有一些触发器来启动你的类(引擎?),这取决于你打算如何使用你的API。

此外,您可以检查模板方法设计模式,因为它可能对您的案例有用,实质上,它允许您解决算法的粗线并定义您希望客户重新定义/扩展哪些部分。 / p>

答案 1 :(得分:1)

好吧,有很多方法可以做到这一点。一种简单的方法是让客户端将子类的名称作为系统属性传递。 main可以使用System.getProperty("prop.name")访问类名。

另一种方法是使用Services API来查找实现类。请参阅https://docs.oracle.com/javase/tutorial/ext/basics/spi.html#the-serviceloader-class

话虽如此,你所描述的内容很奇怪,因为客户端代码本身通常应该有自己的main

答案 2 :(得分:1)

库首先不应该有主类。弥补您的主要内容:应用程序或库。

或许您正在寻找的是抽象工厂模式。

答案 3 :(得分:1)

您可以使用java.util.ServiceLoader加载ParentClass的实例,但有些事情需要考虑:

  • 需要将文件添加到包含实现ParentClass,filename META-INF/services/ParentClass的类的jar中(将ParentClass替换为所实现的类的完全限定名称)。对于实现ParentClass的每个类,您需要在此文件中添加一行,其中包含实现类的完全限定名称。
  • 所有这些类都需要支持使用public无参数构造函数创建类。

实施例

你的罐子

package mypackage;
// used interface here, since in this case there's no reason to use
// a class
// you could use a class here too
public interface ParentClass {
    public void doWork();
}
public class Main {

    public static void main(String [] args) {
        // execute doWork of every ParentClass provided
        for (ParentClass parent : ServiceLoader.load(mypackage.ParentClass.class)) {
            parent.doWork();
        }
    }

}

jar实现ParentClass

package mypackage2;

public class ImplementingClass implements ParentClass {

    @Override
    public void doWork() {
       // Custom implementation
       System.out.println("Hello world");
    }
}

META-INF /服务/ mypackage.ParentClass

mypackage2.ImplementingClass

然后,您只需在执行程序时将其他jar添加到类路径中。

答案 4 :(得分:0)

无需依赖您提供的主要方法。如果他们可以扩展您的类,他们可以在自己的主方法中创建扩展类的对象。