Java会自动将接口转换为子类型。

huangapple go评论70阅读模式
英文:

Java automatically convert interface to subtype

问题

I came across a problem where I have implemented a method for all 4 subtypes of an interface. However, when calling that method with a variable that is of the supertype, it won't let me. I can explicitly use instanceof to check with one, but I need to implement a function that calls 2 instances of the interface.

我遇到了一个问题,我已经为接口的4个子类型实现了一个方法。然而,当我使用一个超类型的变量调用该方法时,它不允许我这样做。我可以显式使用 instanceof 来检查一个,但我需要实现一个函数来调用接口的2个实例。

I already tried checking the 2 instances separately and casting them, but it doesn't work. A solution would be to create if-else with 16 branches to check each combination, but that isn't ideal.

我已经尝试分别检查这两个实例并进行强制转换,但这不起作用。一个解决方案是创建一个 if-else 语句,有16个分支来检查每个组合,但这并不理想。

public interface FormulaVisitor<Result, AdditionalArg> {
    
    Result visit(Atom formula, AdditionalArg a);
    Result visit(BinaryOperator formula, AdditionalArg a);
    Result visit(Constant formula, AdditionalArg a);
    Result visit(Not formula, AdditionalArg a);

}
英文:

So I came across a problem where I have implemented a method for all 4 subtypes of an interface. However, when calling that method with a variable that is of the supertype, it won't let me. I can explicitly use instanceof to check with one, but I need to implement a function that calls 2 instances of the interface.

I already tried checking the 2 instances separately and casting them, but it doesn't work. A solution would be to create if-else with 16 branches to check each combination, but that isn't ideal.

public interface FormulaVisitor &lt;Result , AdditionalArg &gt; {
    
    Result visit(Atom formula, AdditionalArg a);
    Result visit(BinaryOperator formula , AdditionalArg a);
    Result visit(Constant formula , AdditionalArg a);
    Result visit(Not formula , AdditionalArg a);

    }

答案1

得分: 1

I assume you have a Formula interface which is implemented by Atom, Constant, BinaryOperator and Not.

So create a method in your visitor which accepts a Formula and then delegate to other methods. So I would write something like:

public interface FormulaVisitor &lt;Result , AdditionalArg&gt; {
    default Result visit(Formula formula, AdditionalArg a) {
        return switch(formula) {
            case Atom atom -&gt; visit(atom, a);
            case Constant constant -&gt; visit(constant, a);
            case BinaryOperator binaryOperator -&gt; visit(binaryOperator, a);
            case Not not -&gt; visit(not, a);
            default -&gt; null; // if your Formula interface is sealed to 4 classes, this line is not needed
        }
    }

    Result visit(Atom formula, AdditionalArg a);
    Result visit(BinaryOperator formula, AdditionalArg a);
    Result visit(Constant formula, AdditionalArg a);
    Result visit(Not formula, AdditionalArg a);
}

If your interface has just these 4 implementations, make it `sealed`!

As it's a default method in your interface, your are not forced to re-implement it in sub-classes.

In Java method calls are binded during compile time, so the subtype is not recognized then.

<details>
<summary>英文:</summary>

I assume you have a `Formula` interface which is implemented by `Atom`, `Constant`, `BinaryOperator` and `Not`.

So create a method in your visitor which accepts a `Formula` and then delegate to other methods. So I would write something like:

    public interface FormulaVisitor &lt;Result , AdditionalArg&gt; {
        default Result visit(Formula formula, AdditionalArg a) {
            return switch(formula) {
                case Atom atom -&gt; visit(atom, a);
                case Constant constant -&gt; visit(constant, a);
                case BinaryOperator binaryOperator -&gt; visit(binaryOperator, a);
                case Not not -&gt; visit(not, a);
                default -&gt; null; // if your Formula interface is sealed to 4 classes, this line is not needed
            }
        }

        Result visit(Atom formula, AdditionalArg a);
        Result visit(BinaryOperator formula, AdditionalArg a);
        Result visit(Constant formula, AdditionalArg a);
        Result visit(Not formula, AdditionalArg a);
    }

If your interface has just these 4 implementations, make it `sealed`!

As it&#39;s a default method in your interface, your are not forced to re-implement it in sub-classes.

In Java method calls are binded during compile time, so the subtype is not recognized then.

</details>



# 答案2
**得分**: 0

如果您正在指的是`Atom`,`BinaryOperator`等具有共同的超类型并且您只知道共同的超类型您很不幸 - 您不能简单地调用这四种方法并希望一切顺利

调用的确切函数是在编译时静态确定的

如果您打算实现完整的[访问者模式][1]您可以让这四种类型实现对适当的访问方法的调用例如通过共同超类型声明`accept(Visitor visitor)`,并在每个子类型中实现适当的调用


  [1]: https://en.wikipedia.org/wiki/Visitor_pattern

<details>
<summary>英文:</summary>

If you&#39;re referring to `Atom`, `BinaryOperator` etc having a common supertype and you know only the common supertype: You&#39;re out of luck - you can&#39;t simply call those 4 methods and hope for the best:

The exact function that&#39;s called is determined statically, at compile time.

If you intend to implement the full [Visitor pattern][1], you&#39;d have the 4 types implement the call to an appropriate visit method, e.g. by the common supertype declaring `accept(Visitor visitor)`, and implementing the proper call in each subtype. 


  [1]: https://en.wikipedia.org/wiki/Visitor_pattern

</details>



huangapple
  • 本文由 发表于 2023年5月15日 00:26:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76248556.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定