带抽象参数和继承的Java抽象方法 [英] Java abstract method with abstract parameter and inheritance

查看:138
本文介绍了带抽象参数和继承的Java抽象方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到了API的问题以及出现以下类型代码的实现:

I recently fumbled into a problem with an API and an implementation where the following type of code appeared:

API是一个抽象类:

The API is an abstract class:

public abstract class A {
 public A sum(A a) {
  System.out.println("A.sum(A) called");
  return null;
 }
}

实现是一个简单的类:

public class B extends A {
 public B sum(B b) {
  System.out.println("B.sum(B) called");
  return null;
 }
}

说到使用它我写道:

public class Main {

  public static void main(String args[]) {
    B b = new B();
    A basa = new B();

    b.sum(b);
    basa.sum(b);
    basa.sum(basa);
  }  
}

结果如下:

% java Main
B.sum(B) called
A.sum(A) called
A.sum(A) called

我知道B的总和不会覆盖A的总和,因为它的签名不同,但我我希望为有效类型B的对象提供有效的sum实现。我认为这样的设计非常经典,现在我想如何设计我的API和实现,以便它有效。

I understand that B's sum does not override A's sum as its signature is different, but I'd like to provide an efficient implementation of sum for objects of effective type B. I think such design is quite classical and would like to now how I should design my API and implementation so that it is efficient.

当然,我可以在类中提供sum(A a)并在调用sum(B)或super之前检查b是否是instanceOf B,但我认为要避免使用instanceOf效率原因(如果它效率低下,它的效率可能会低于我的抽象实现。

Of course, I could provide sum(A a) in class be and check if b is an instanceOf B before calling either sum(B) or super, but I thought that instanceOf was to be avoided for efficiency reasons (if it is inefficient, it may be even less efficient as my "abstract" implementation.

推荐答案

instanceof 通常可以通过使用访问者模式来避免。根据您的需要,它可能是也可能不是过度的l。它很灵活但很冗长。在下面的示例中,我从 A 中删除​​了 abstract ,以说明它如何与不同类型一起使用。

instanceof can usually be avoided by using the visitor pattern. Depending on your needs, it may or may not be an overkill. It's flexible but quite verbose. In the example below I removed abstract from A to illustrate how it works with different types.

诀窍是,当要求对象访问访问者时,对象本身会在访问者中选择正确的 accept 方法。 instanceof-check通过多态解决。 (我怀疑它比 instanceof 更有效。)

The trick is that when an object is asked to visit a visitor, the object itself chooses the correct accept method in the visitor. The "instanceof"-check is resolved through polymorphism. (I doubt that it's more efficient than an instanceof though.)

interface Visitor {
    public A accept(A a);
    public B accept(B b);
}

class A {
    public A sum(A a) {
        System.out.println("A.sum(A) called");
        return null;
    }

    public A visit(Visitor sv) {
        return sv.accept(this);
    }
}

class B extends A {
    public B sum(B b) {
        System.out.println("B.sum(B) called");
        return null;
    }

    public B visit(Visitor sv) {
        return sv.accept(this);
    }
}

public class Test {

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        A basa = new B();

        a.visit(new SumVisitor(b));        // a.sum(b);
        b.visit(new SumVisitor(b));        // b.sum(b);
        basa.visit(new SumVisitor(b));     // basa.sum(b);
        basa.visit(new SumVisitor(basa));  // basa.sum(basa);
    }

    static class SumVisitor implements Visitor {
        A arg;
        SumVisitor(A arg) { this.arg = arg; }
        public A accept(A a) { return a.sum(arg); }
        public B accept(B b) { return b.sum(arg); }
    }
}

输出:

A.sum(A) called
B.sum(B) called
B.sum(B) called
B.sum(B) called

Disclamer;不久前我写了一个访问者,所以如果我在这个(几乎未经测试的)代码片段中有任何错误,请纠正我。或者更好,自己编辑帖子并改进它:)

Disclamer; It was a while ago I wrote a visitor, so please correct me if I have any bugs in this (almost untested) code snippet. Or better, edit the post yourself and improve it :)

这篇关于带抽象参数和继承的Java抽象方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆