英文:
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 <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);
}
答案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 <Result , AdditionalArg> {
default Result visit(Formula formula, AdditionalArg a) {
return switch(formula) {
case Atom atom -> visit(atom, a);
case Constant constant -> visit(constant, a);
case BinaryOperator binaryOperator -> visit(binaryOperator, a);
case Not not -> visit(not, a);
default -> 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 <Result , AdditionalArg> {
default Result visit(Formula formula, AdditionalArg a) {
return switch(formula) {
case Atom atom -> visit(atom, a);
case Constant constant -> visit(constant, a);
case BinaryOperator binaryOperator -> visit(binaryOperator, a);
case Not not -> visit(not, a);
default -> 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>
# 答案2
**得分**: 0
如果您正在指的是`Atom`,`BinaryOperator`等具有共同的超类型,并且您只知道共同的超类型:您很不幸 - 您不能简单地调用这四种方法并希望一切顺利:
调用的确切函数是在编译时静态确定的。
如果您打算实现完整的[访问者模式][1],您可以让这四种类型实现对适当的访问方法的调用,例如,通过共同超类型声明`accept(Visitor visitor)`,并在每个子类型中实现适当的调用。
[1]: https://en.wikipedia.org/wiki/Visitor_pattern
<details>
<summary>英文:</summary>
If you're referring to `Atom`, `BinaryOperator` etc having a common supertype and you know only the common supertype: You're out of luck - you can't simply call those 4 methods and hope for the best:
The exact function that's called is determined statically, at compile time.
If you intend to implement the full [Visitor pattern][1], you'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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论