Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.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接口与多个实现类一起使用_Java_Interface_Oop - Fatal编程技术网

如何将java接口与多个实现类一起使用

如何将java接口与多个实现类一起使用,java,interface,oop,Java,Interface,Oop,呼叫代码: public interface Foo { } public class SpecificFoo implements Foo { } public interface SomeInterface { void thisMethod(Foo someKindOfFoo); } public class SomeClass implements SomeInterface { public void thisMethod(Foo someKindOfFoo)

呼叫代码:

public interface Foo {
}

public class SpecificFoo implements Foo {
}

public interface SomeInterface {
    void thisMethod(Foo someKindOfFoo);
}

public class SomeClass implements SomeInterface {

    public void thisMethod(Foo someKindOfFoo) {
        // calling code goes into this function
         System.out.println("Dont go here please");
    }

    public void thisMethod(SpecificFoo specificFoo) {
        // not into this function
         System.out.println("Go here please");
    }
}

public class SomeOlderClass {

    public SomeOlderClass( SomeInterface inInterface ) {
        SpecificFoo myFoo = new SpecificFoo();

        inInterface.thisMethod(myFoo);
    }
}
我有一个接口(
SomeInterface
),几个类调用它(比如
SomeOlderClass
)。我有一个实现接口的类,但我想对传递到泛型接口的特定实现执行类型安全操作

如上面代码所示,我确实希望能够生成另一个方法,该方法与传入接口的特定类型相匹配。这不管用。我假设这是因为调用代码只知道接口,而不知道更具体方法的实现(即使
SpecificFoo实现了Foo

那么,我如何才能以最优雅的方式做到这一点呢?我可以通过在实现接口的类(
SomeClass
)中添加if语句来让代码正常工作:

然而,这并不优雅,因为每次我添加一种新的Foo时都必须添加if语句。我可能会忘记这么做

另一个选项是将
SpecificFoo
添加到
SomeInterface
,并让编译器进行排序,提醒我需要在
SomeClass
中实现。问题是,我最终添加了相当多的锅炉板代码。(如果其他人实现了接口,他们必须实现新方法以及任何测试)

考虑到
Foo
SpecificFoo
是相关的,我似乎还缺少另一个选项。想法

更多信息:

实际上,我花了一段时间试图简化这个问题。随着我添加更多的细节,复杂性增加了不少。但不管怎样。。。我想我可以解释

基本上,我正在使用Ray Ryan在他的文章中解释的命令模式编写GWT web apps RPC servlet

google代码上有几种实现,但其中许多都存在继承问题。我认为这是GWT-RPC代码中的一个bug,但是,当我进一步实现时,我注意到一个类似的问题纯粹发生在客户端,而在托管模式下。(即全是java,没有gwt javascript疯狂)

因此,我将基本思想抽象为一个原始java命令行案例,并看到了相同的问题,如上所述

如果您按照Ray Ryan讨论的内容进行操作,
Foo
是一个动作,
SpecificFoo
是我想调用的一个特定动作
SomeInterface
是客户端RPC服务,
SomeClass
是服务器端RPC类
SomeOlderClass
是一种rpc服务,它了解缓存等内容


很明显,对吧?正如我所说的,我认为所有GWT RPC的废话只是在基本问题上弄乱了局面,这就是为什么我尽量简化它。

如果需要在运行时找出对象的实际类型,那么设计很可能是错误的。这至少违反了法律

(因为Java没有,所以将调用
thisMethod(Foo)
,而不是
thisMethod(SpecificFoo)
。可以用来绕过语言的限制,但可能仍然存在一些设计问题……)

请提供更多关于你正在努力完成的事情的信息。目前,这个问题并没有提供足够的信息来提出正确的设计

一个通用的解决方案是,由于操作取决于
Foo
的运行时类型,因此该方法应该是
Foo
的一部分,因此它的实现可以根据
Foo
的类型而变化。因此,您的示例将更改为如下内容(可能会将
SomeInterface
或其他参数添加到
thisMethod()


尝试使用双重分派:将方法添加到
Foo
接口,该接口由
SomeClass\thisMethod
调用。然后将代码放入此方法的实现中

public interface Foo {
    void thisMethod();
}

public class SpecificFoo implements Foo {
        public void thisMethod() {
                 System.out.println("Go here please");
        }
}

抱歉,我发现问题描述太抽象,无法提出建议。您显然存在设计问题,因为您通常不需要检查接口的类型。我会试一试的。。。首先,我需要让你的问题更具体,让我的小脑袋去理解。除了食物,还有鸟呢

public interface Foo {
  public void thatMethod(SomeClass a);
  public void thatMethod(SomeOlderClass a);
}

public class SomeClass implements SomeInterface {
    public void thisMethod(Foo someKindOfFoo) {
        someKindOfFoo.thatMethod(this);
    }
}
在这里,鸵鸟会宣布“我在空中,耶!”这不是我们想要的

好的,所以,忽略我在这里失败的基本OO这一事实,问题是BirdManager将寻找与传入的类型匹配的最不特定的方法。因此,无论我给它什么样的鸟,它都将永远匹配
fly(bird)
。如果检查,我们可以在那里放置一些
,但随着你添加更多类型的鸟类,你的设计将进一步退化。这里是棘手的部分-我不知道这是否有道理在您的问题的背景下,但考虑这种重构,我把逻辑从经理到鸟:< /P>
public interface Bird {
}

public class Ostrich implements Bird {
}

public interface BirdManager {
    void fly(Bird bird);
}

public class AdvancedBirdManager implements BirdManager {

    public void fly(Bird bird) {
        System.out.println("I am in the air. Yay!");
    }

    public void fly(Ostrich ostrich) {
        System.out.println("Sigh... I can't fly.");
    }
}

public class ZooSimulation {
    public ZooSimulation(BirdManager birdManager) {
        Ostrich ostrich = new Ostrich();
        birdManager.fly(ostrich);
    }
}

public static void main(String[] args) {
    AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
    ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}

我们的鸵鸟现在说的是正确的话,鸟类经理仍然把它当作一只鸟。同样,糟糕的OO(鸵鸟不应该有
fly()
方法),但它说明了我的想法。

只要
Foo
的实现不太多,我就会在
SomeInterface
中为
Foo
的每个子类声明一个抽象方法,并有一个抽象类转发调用为最一般类型定义的默认方法:

public interface Bird {
    void fly();
}

public class BasicBird implements Bird {
    public void fly() {
        System.out.println("I am in the air. Yay!");
    }
}

public class Ostrich implements Bird {
    public void fly() {
        System.out.println("Sigh... I can't fly.");
    }
}

public interface BirdManager {
    void fly(Bird bird);
}

public class AdvancedBirdManager implements BirdManager {

    public void fly(Bird bird) {
        bird.fly();
    }
}

public class ZooSimulation {
    public ZooSimulation(BirdManager birdManager) {
        Ostrich ostrich = new Ostrich();
        birdManager.fly(ostrich);
    }
}

public static void main(String[] args) {
    AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
    ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}

为什么血从我的耳朵里流出来。自我提示:使用鸟类,而不是食物。:)谢谢,这有点帮助。我认为在我的例子中,像您所做的那样将逻辑移到类中是不可行的。正如我在上面解释的,这些对象是操作,涉及服务器端特定的代码。虽然它不会在客户端执行,但我不知道GWT是否愿意在客户端代码中包含这些内容。嗯,不过我不太确定。
public interface Bird {
}

public class Ostrich implements Bird {
}

public interface BirdManager {
    void fly(Bird bird);
}

public class AdvancedBirdManager implements BirdManager {

    public void fly(Bird bird) {
        System.out.println("I am in the air. Yay!");
    }

    public void fly(Ostrich ostrich) {
        System.out.println("Sigh... I can't fly.");
    }
}

public class ZooSimulation {
    public ZooSimulation(BirdManager birdManager) {
        Ostrich ostrich = new Ostrich();
        birdManager.fly(ostrich);
    }
}

public static void main(String[] args) {
    AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
    ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
public interface Bird {
    void fly();
}

public class BasicBird implements Bird {
    public void fly() {
        System.out.println("I am in the air. Yay!");
    }
}

public class Ostrich implements Bird {
    public void fly() {
        System.out.println("Sigh... I can't fly.");
    }
}

public interface BirdManager {
    void fly(Bird bird);
}

public class AdvancedBirdManager implements BirdManager {

    public void fly(Bird bird) {
        bird.fly();
    }
}

public class ZooSimulation {
    public ZooSimulation(BirdManager birdManager) {
        Ostrich ostrich = new Ostrich();
        birdManager.fly(ostrich);
    }
}

public static void main(String[] args) {
    AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
    ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
public interface Foo {
}

public class SpecificFoo implements Foo {
}

public interface SomeInterface {
        void thisMethod(Foo someKindOfFoo);
        void thisMethod(SpecificFoo specificFoo);
        void thisMethod(OtherSpecificFoo otherSpecificFoo);
}

public abstract class AbstractSomeInterface {
        public void thisMethod(Foo wrongFoo) {
            throw new IllegalArgumentException("Wrong kind of Foo!");
        }

        public void thisMethod(SpecificFoo specificFoo) {
            this.thisMethod((Foo) specificFoo);
        }

        public void thisMethod(OtherSpecificFoo otherSpecificFoo) {
            this.thisMethod((Foo) specificFoo);
        }
}

public class SomeClass extends AbstractSomeInterface {
        public void thisMethod(SpecificFoo specificFoo) {
                 // calling code goes into this function
                 System.out.println("Go here please");
        }
}

public class SomeOlderClass {

        public SomeOlderClass( SomeInterface inInterface ) {
                SpecificFoo myFoo = new SpecificFoo();

                inInterface.thisMethod(myFoo);
        }
}