接受两种不同类型作为参数的方法

Joh*_*Eye 27 java generics polymorphism overloading

我正在编写一个方法,它应该接受两个类型之一的对象作为其参数,这两个类型不共享除Object之外的父类型.例如,类型是梦想和大蒜.你都可以做dreams.crush()garlic.crush().我想要一个方法utterlyDestroy(parameter),它将接受Dreams和Garlic作为它的参数.

utterlyDestroy(parameter) {
    parameter.crush()
}
Run Code Online (Sandbox Code Playgroud)

Garlic和dream都是某个库的一部分,所以让它们实现一个接口ICrushable(这样我可以写utterlyDestroy(ICrushable parameter))不是一个选项.

我的方法体很长,所以重载就意味着重复代码.丑陋.我相信我可以使用反射并做一些类黑客攻击.丑陋.

我尝试使用泛型,但显然我不能写类似的东西

utterlyDestroy(<T instanceof Dreams || T instanceof Garlic> parameter)
Run Code Online (Sandbox Code Playgroud)

是否有可能将大蒜强加给梦想?

utterlyDestroy(Object parameter) {
    ((Dreams)parameter).crush()
}
Run Code Online (Sandbox Code Playgroud)

但这仍然是丑陋的.我的其他选择是什么?处理这种情况的首选方法是什么?

Dev*_*ler 31

这个怎么样:

interface ICrushable {
    void crush();
}

utterlyDestroy(ICrushable parameter) {
    // Very long crushing process goes here
    parameter.crush()
}

utterlyDestroy(Dreams parameter) {
    utterlyDestroy(new ICrushable() { crush() {parameter.crush();});
}

utterlyDestroy(Garlic parameter) {
    utterlyDestroy(new ICrushable() { crush() {parameter.crush();});
}
Run Code Online (Sandbox Code Playgroud)

新开发应该实现ICrushable接口,但对于现有的Classes,参数包装在ICrushable中并传递给完成所有工作的utterlyDestroy(ICrushable).


Aar*_*oup 6

您可以在 Java 中实现 Haskell 式的任一类;像这样:

class Either<L,R>
{
    private Object value;

    public static enum Side {LEFT, RIGHT}

    public Either(L left)  {value = left;}
    public Either(R right) {value = right;}

    public Side getSide() {return value instanceof L ? Side.LEFT : Side.RIGHT;}

    // Both return null if the correct side isn't contained.
    public L getLeft() {return value instanceof L ? (L) value : null;}
    public R getRight() {return value instanceof R ? (R) value : null;}
}
Run Code Online (Sandbox Code Playgroud)

然后你让那个方法接受 type 的东西Either<Dreams, Garlic>


Cra*_*lus 6

这么简单的事怎么样?

utterlyDestroy(Object parameter) {    
    if(parameter instanceOf Dreams){  
        Dream dream = (Dreams)parameter;  
        dream.crush();
        //Here you can use a Dream 
    }  
    else if(parameter instanceOf Garlic){  
       Garlic garlic = (Garlic)parameter;   
        //Here you can use a Garlic  
       garlic.crush();  
   }
} 
Run Code Online (Sandbox Code Playgroud)

如果utterlyDestroy它过于复杂和大而你只想打电话给crush那么这就是你想要的

  • 当然这发生在我身上,但使用Object作为参数似乎是错误的. (2认同)
  • 你不是在这里重复相同的代码吗?对我没有意义. (2认同)