我们如何使用Java接口强制实现双向接口?

时间:2014-02-27 13:04:48

标签: java interface private observer-pattern

Java不允许私有或受保护的方法,那么我们如何确保双向接口的实现者调用必要的方法呢?

假设我们有一个IModelListener接口,如下所示:

public interface IModelListener
{   
    public void handleChannelUpdate(int channel);
}

然后我们有一个ViewControl客户端,如下所示:

public class ViewControl implements IModelListener
只要我们记得让ViewControl调用它,

ViewControl对象就会起作用:

model.registerChannelListener(this);

如果Java允许接口中的受保护或私有方法,我们可以简单地将IModelListener修改为:

public interface IModelListener
{   
    public void handleChannelUpdate(int channel);
    private void registerChannelListener( );
}

如何实现这一目标? 是否有注释可以做到这一点?

Java不支持多重继承,因此如果客户端/实现者已经是派生类(典型),那么使用抽象类不是一种选择。

感谢您的帮助, 杰夫

6 个答案:

答案 0 :(得分:3)

您可能会错过接口的概念。它不能包含私有或受保护的方法,因为接口的作用是提供一组可访问的方法。另一方面,你可能会看一下抽象类。

您需要的可能是:

public abstract class AbstractViewControler implements IModelListener {

    protected abstract void registerChannelListener();

    protected AbstractViewControler() {
        this.registerChannelListener();
    }
}

然后:

public class MyViewControler extends AbstractViewControler {

    protected void registerChanelListener() {
        //- Do what you need here.
    }
}

之后只是:

IModelListener listner = new MyViewControler();

答案 1 :(得分:1)

接口是一种向实现接口的类的用户提供公共合同的方法。只要他们遵守合同,如何实施课程并不重要。因此,在接口中使用私有方法是没有意义的。

答案 2 :(得分:0)

您想要的是在您的类上强制执行默认行为 - 在Java中,抽象类是制定所有扩展类继承的默认行为的地方(请参阅此应用程序的模板方法设计模式)。接口仅描述对象外部行为的方式以及其他人如何使用它们。

答案 3 :(得分:0)

java中的接口旨在提供您在类中实现的签名的接口功能的签名,因此它不应该是私有的。

您的需求:您可以使用您想要的一些默认语句的抽象方法。

您可以拥有所有类型的访问权限。

答案 4 :(得分:0)

在Java中,您不能仅使用接口来执行此操作。

如果你想实现某种“自动绑定”(即在所有相关对象上自动调用model.registerChannelListener(this);),那么你应该让这些对象实现一个空接口,检索实现类的所有实例的列表它通过内省并迭代它们。

您可以定期或在程序中的某个特定点执行此操作。您还可以使用@interface注释添加一点语法糖。

您可能还想使用依赖注入和/或工厂来反转流并创建对象,这样您就可以在创建后立即使用“自动”方法(与@PostConstruct一样)。

答案 5 :(得分:0)

接口是错误的地方。

Java中用于此类问题的常用解决方案是在任一对象中都有一个返回另一个的方法:

public class ViewControl {
    public IModel getModel() {...}
}

然后,该方法可以确保正确连接模型和视图。现在我猜你真的不想结合视图和模型。然后解决方案是定义一个新的ViewModel类型,它只委托给真实模型(大多数IDE允许创建委托类型,只需点击3-5次):

public class ViewControl {
    public ViewModel getViewModel( IModel model ) {...}
}

您应该能够将此代码移动到所有视图继承的基础(abstract)视图类。