Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 接口xxx不能用不同的参数实现多次: 实现GenericObserver,GenericObserver_Java - Fatal编程技术网

Java 接口xxx不能用不同的参数实现多次: 实现GenericObserver,GenericObserver

Java 接口xxx不能用不同的参数实现多次: 实现GenericObserver,GenericObserver,java,Java,不能使用不同的参数多次实现 这是我的界面: implements GenericObserver<DataService, Tools>, GenericObserver<MobileService, Tools> 公共接口GenericObserver{ 无效更新(S发件人、D数据); } 我能做什么?我需要DataService和MobileService 我尝试使用genericT而不是DataService和MobileService但是我得到了一个错误,T不

不能使用不同的参数多次实现

这是我的界面:

implements GenericObserver<DataService, Tools>, GenericObserver<MobileService, Tools>
公共接口GenericObserver{
无效更新(S发件人、D数据);
}
我能做什么?我需要
DataService
MobileService

我尝试使用generic
T
而不是
DataService
MobileService
但是我得到了一个错误,
T
不存在

一种可能性:

public interface GenericObserver<S, D> {

    void update(S sender, D data);
}
抽象类服务{}
类DataService扩展服务{}
类MobileService扩展服务{}
类Foo实现GenericObserver{
无效更新(服务发件人、工具数据){
if(数据服务的发送方实例){
//做点什么
}else if(MobileService的发送方实例){
//做点别的
}否则{
//抛出一些未实现的异常
}
}
}

这是另一种可能性(
GenericObserver
是可访问的)。

这是因为Java在做。编译后,所有泛型类型都会被删除,两个接口在字节码中看起来都一样。

我看到了两种可能的情况,为什么要这样做:

第一个-GenericObserver和GenericObserver对于实现类接口都是必不可少的。在这种情况下,您可能存在设计缺陷,因为对象应尽可能专门化(即,最好有两个不同的类,每个类都专注于专门的任务,而不是一个类将两者混合)。因此,您可能应该创建两个单独的类,一个实现GenericObserver,另一个实现GenericObserver。当您尝试使用不同的类型参数实现GenericObserver两次时,编译器会抱怨,因为Java中的泛型是使用擦除实现的,因此GenericObserver和GenericObserver在运行时基本上是同一个GenericObserver

第二个场景-这些接口是实现细节的一部分。然后您可以使用内部类(或静态嵌套类)来实现您的目标。例如:

abstract class Service {}

class DataService extends Service {}

class MobileService extends Service {}

class Foo implements GenericObserver<Service, Tools> {
    void update(Service sender, Tools data) {
        if (sender instanceOf DataService) {
            // do something
        } else if (sender instanceOf MobileService) {
            // do something else
        } else {
            // throw some notImplemented exception
        }
    }
}
公共类外部类{
私有字符串hello=“hello”;
私有字符串world=“world”;
私有类InnerClass1实现GenericObserver{
公共字符串接口方法(){
返回hello+“”+世界;
}
//更多实施
}
私有类InnerClass2实现GenericObserver{
//实施
}
}

如果您使用内部类,那么您可以很容易地访问包含类的字段,正如您从这个有点做作的示例中所看到的。

实现类可以提供这些接口,作为提供以下查找方法的功能。这种模式的优点是类的API的可扩展性和不耦合性

public class OuterClass {

    private String hello = "Hello";
    private String world = "World";

    private class InnerClass1 implements GenericObserver<DataService, Tools> {
        public String interfaceMethod() {
            return hello + " " + world;
        }
        // more implementation
    }

    private class InnerClass2 implements GenericObserver<MobileService, Tools> {
        // implementation
    }

}
接口DataObserver扩展了GenericObserver{}
接口MobileObserver扩展了GenericObserver{}
公共类实现器{
私有数据观察者;
专用移动观察服务器;
公共T查找(klazz类){
…返回数据观察器;
}
}

它的可能重复项不是字符串。这是类而不是字符串…@AdamMatan:这个特殊的问题看起来更多的是关于Eclipse Java 1.7编译器的一个特殊怪癖(即bug),而不是关于实现一个通用接口的两个实例化的一般问题。关于这一点肯定存在一些问题,但这不是其中之一。@TomAnderson,谢谢,我在这一点上太草率了。也可以使用相同的泛型。供参考:
interface DataObserver extends GenericObserver<DataService, Tools> { }

interface MobileObserver extends GenericObserver<MobileService, Tools> { }

public class Implementor {

    private DataObserver dataObserver;
    private MobileObserver mobileObserver;

    public <T> T lookup(Class<T> klazz) {
        ... return dataObserver;
    }

}