Java重载:如何调用更具体的函数

huangapple 未分类评论44阅读模式
英文:

Java overload: how to call more specific one

问题

以下是翻译好的内容:

我的程序解析 `WebAssembly` 指令并根据当前指令的上下文进行决策因此我的算法的最小可行示例MWE如下所示

public class Main {
    public interface Context {
        String name();
    }
    static class M implements Context {
        public String name() {
            return "Context M: ";
        }
    }
    static class N implements Context {
        public String name() {
            return "Context N: ";
        }
    }

    public interface Instruction {
        int getId();

        String run();
    }

    static class A implements Instruction {
        public int getId() {
            return 0;
        }

        public String run() {
            return "A的工作";
        }
    }

    static class B implements Instruction {
        public int getId() {
            return 1;
        }

        public String run() {
            return "B的工作";
        }
    }

    static void work(Context context, Instruction instruction) {
        switch (instruction.getId()) {
            case 0:
                workOnId0(context, (A) instruction);
                break;
            case 1:
                workOnId1(context, (B) instruction);
                break;
            default:
                throw new RuntimeException("无法识别的指令");
        }
    }

    static void workOnId0(Context context, A instruction) {
        System.out.println(context.name() + instruction.run());
    }

    static void workOnId1(Context context, B instruction) {
        System.out.println(context.name() + instruction.run());
    }

    static void workOnId1(N context, B instruction) {
        System.out.println("这是针对该上下文的特殊逻辑!");
    }

    public static void main(String[] args) {
        N context = new N();
        B instruction = new B();

        work(context, instruction);
    }
}

正如你从上面所看到的,当我的指令是 B 时,普通的工作应该在 workOnId1 中发生,但是在上下文特定为 N 的情况下,我希望进行一些特殊的工作,这由 workOnId1 的不同重载表示。

不幸的是,特殊的重载从未被调用。我该如何使重载的解析工作?

英文:

My program parses WebAssembly instructions and makes decisions based on the context of the current instruction. So, the MWE for my algorithm looks like this:

public class Main {
    public interface Context {
        String name();
    }
    static class M implements Context {
        public String name() {
            return "Context M: ";
        }
    }
    static class N implements Context {
        public String name() {
            return "Context N: ";
        }
    }

    public interface Instruction {
        int getId();

        String run();
    }

    static class A implements Instruction {
        public int getId() {
            return 0;
        }

        public String run() {
            return "The work of A";
        }
    }

    static class B implements Instruction {
        public int getId() {
            return 1;
        }

        public String run() {
            return "The work of B";
        }
    }

    static void work(Context context, Instruction instruction) {
        switch (instruction.getId()) {
            case 0:
                workOnId0(context, (A) instruction);
                break;
            case 1:
                workOnId1(context, (B) instruction);
                break;
            default:
                throw new RuntimeException("Failed to recognize instruction");
        }
    }

    static void workOnId0(Context context, A instruction) {
        System.out.println(context.name() + instruction.run());
    }

    static void workOnId1(Context context, B instruction) {
        System.out.println(context.name() + instruction.run());
    }

    static void workOnId1(N context, B instruction) {
        System.out.println("This is corner case logic for this context!");
    }

    public static void main(String[] args) {
        N context = new N();
        B instruction = new B();

        work(context, instruction);
    }
}

As you can see from above, when my instruction is B, then the ordinary work should happen in workOnId1, but in case my context is specifically N, I would like some special work done, which is represented by a different overload of workOnId1.

Unfortunately, the special overload never gets called. How can I make the overload resolution work?

答案1

得分: 0

workOnId1(Context context, B instruction) 将会始终被调用,因为您有一个 Context 对象。

您需要通过将调用方法转换为 N 来进行区分。如果这在您的模型内效果不佳,因为我猜这只是一个小例子,您可能需要重新思考整体设计。一个简单的解决方案是:

if (context instanceof N) {
   workOnId1((N) context, (B) instruction);
} else {
   workOnId1(context, (B) instruction);
}
英文:

workOnId1(Context context, B instruction) will always be called, because you have a Context object.

You are going to need to differentiate method calls by casting to N. If this doesn't work well within your model, since I'm guessing this is only a small example, you may need to rethink your overall design. A simple solution would be:

if(context instanceof N) {
   workOnId1((N)context, (B)instruction);
} else {
   workOnId1(context, (B) instruction);
}

答案2

得分: 0

你可以将 case:1 下的一行代码更改为以下内容,以实现你的目标:

switch (instruction.getId()) {
    case 0:
        workOnId0(context, (A) instruction);
        break;
    case 1:
        workOnId1((context instanceof N) ? (N)context : context, (B) instruction);
        break;
    default:
        throw new RuntimeException("无法识别的指令");
}
英文:

you can change one line under case:1 as below to achieve your target

switch (instruction.getId()) {
            case 0:
                workOnId0(context, (A) instruction);
                break;
            case 1:
                workOnId1((context instanceof N)? (N)context :context, (B) instruction);                break;
            default:
                throw new RuntimeException("Failed to recognize instruction");
        }

huangapple
  • 本文由 发表于 2020年4月8日 02:01:05
  • 转载请务必保留本文链接:https://java.coder-hub.com/61086448.html
匿名

发表评论

匿名网友

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

确定