Java抽象方法具有抽象参数和继承
我最近摸索到一个 API 和实现的问题,其中出现了以下类型的代码:
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);
}
}
结果是:
B.sum(B) called
A.sum(A) called
A.sum(A) called
我明白 B 的总和不会覆盖 A 的总和因为它的签名不同,但我想为有效类型 B 的对象提供 sum 的有效实现。我认为这种设计非常经典,我想知道我应该如何设计我的 API 和实现,以便它高效的。
当然,我可以在 B 类中提供 sum(A a) 并在调用 sum(B b) 之前检查 b 是否是 B 的实例或 super,但我认为出于效率原因应避免使用 instanceof
。 (如果效率低下,我的抽象实现的效率可能会更低)
I recently fumbled into a problem with an API and an implementation where the following type of code appeared:
public abstract class A {
public A sum(A a) {
System.out.println("A.sum(A) called");
return null;
}
}
The implementation is a simple class:
public class B extends A {
public B sum(B b) {
System.out.println("B.sum(B) called");
return null;
}
}
When it comes to using it I write:
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);
}
}
Which results in:
B.sum(B) called
A.sum(A) called
A.sum(A) called
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 I would like to know how I should design my API and implementation so that it is efficient.
Of course I could provide sum(A a)
in class B and check if b is an instanceof
B before calling either sum(B 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 with my abstract implementation)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
instanceof
通常可以通过使用访问者模式来避免。根据您的需求,这可能会也可能不会太过分。它很灵活,但相当冗长。在下面的示例中,我从A
中删除了abstract
以说明它如何与不同类型一起工作。诀窍在于,当一个对象被要求访问访问者时,该对象本身会在访问者中选择正确的
accept
方法。 “instanceof”检查是通过多态性解决的。 (不过,我怀疑它比instanceof
更有效。)输出:
免责声明;不久前我写了一个访问者,所以如果我在这个(几乎未经测试的)代码片段中有任何错误,请纠正我。或者更好的是,自己编辑帖子并改进它:)
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 removedabstract
fromA
to illustrate how it works with different types.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 aninstanceof
though.)Output:
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 :)
由于可以使用
myA.sum(myB)
将B
实例与A
实例相加,因此您应该能够更改B
B code> 对sum
的定义,以便它确实被覆盖,当然,除非sum
是一个占位符并且不应该是可交换的。更新:
如果这还不够,您可以开始喜欢泛型。这是我的意思的粗略传递:
@aioobe 是正确的,普遍接受的解决方法是使用访问者模式。我提供这些作为不太完整但不太冗长的替代方案。
Since
B
instances can be summed withA
instances usingmyA.sum(myB)
, you should be able to changeB
's definition ofsum
so that it does override, unless of coursesum
is a placeholder and isn't something that should be commutative.UPDATE:
If this is insufficient, you could start getting fancy with generics. Here's a rough pass at what I mean:
@aioobe is right that the generally accepted work-around is to use the Visitor pattern. I'm offering these as less complete but less verbose alternatives.
那么,是什么让您认为
instanceof
很慢?它被用在 JDK 中的多个地方,他们希望为抽象类或接口的某些众所周知的实现提供“快速路径”。通常的建议在这里适用:“测试,不要猜测。”So, what makes you think
instanceof
is slow? It's used in several places in the JDK where they want to provide a "fast path" for certain well-known implementations of an abstract class or interface. The usual advice applies here: "Test, don't guess."