Java 如何确保我的抽象类';s函数只能在与调用者类型相同的扩展器上运行?

Java 如何确保我的抽象类';s函数只能在与调用者类型相同的扩展器上运行?,java,abstract-class,Java,Abstract Class,例如,假设这是我的抽象类: abstract class A{ int x; int y; void foo(A fooMe); } …和B和C是扩展A的两个类 我想要的是B只能在其他Bs上调用foo(),而C只能在其他Cs上调用foo()。但是我希望这不受扩展我的A类的程序员的控制-也就是说,我希望有一种方法能够确保As代码中的这一功能 我能做什么?(如果可能的话)我希望避免任何太混乱的黑客或泛型解决方案-我仍然希望foo能够被这样调用,例如: B b=new B(

例如,假设这是我的抽象类:

abstract class A{
    int x;
    int y;

    void foo(A fooMe);
}
…和
B
C
是扩展
A
的两个类

我想要的是
B
只能在其他
B
s上调用
foo()
,而
C
只能在其他
C
s上调用
foo()
。但是我希望这不受扩展我的
A
类的程序员的控制-也就是说,我希望有一种方法能够确保
A
s代码中的这一功能

我能做什么?(如果可能的话)我希望避免任何太混乱的黑客或泛型解决方案-我仍然希望
foo
能够被这样调用,例如:

B b=new B();
B bb=new B();
bb.foo(b);


编辑:如果有人有任何想法,我现在愿意接受使用泛型的解决方案。。。(我想不出一个)

您可以在
A
中将
foo
设为
final
,并按如下方式实现它:让它引发异常,除非
fooMe.getClass()
等于
this.getClass()
,否则调用抽象方法
fooohook
。当然,子类必须重写
fooHook
,而不是
foo


我相信最后的加钩子方法是不可避免的:如果一个子类可以覆盖
foo
,那么
a
的代码本身就无法保证在其
foo
中执行的任何检查都不会被一个子类轻松绕过。

这里有一个技巧,但它不是编译时间。我不认为Java泛型没有足够的协变/逆变类型支持


class B extends A {
    @Override
    void foo(A foome) {
        if (foome.getClass() != getClass()) {
            throw new UnsupportedOperationException("...");
        }
    }
}

如果您使用面向方面的编程,就可以实现这样的功能。在建议检查并抛出违反您要求的异常之前。

(+1)这是一个很酷的想法。如果我找不到另一个解决方案,我肯定会使用它——尽管我最希望在编译时发现任何这样的错误,而不是在运行时。@incrediman,不幸的是,我不相信你能在编译时得到它,至少在没有你想要避免的混乱泛型的情况下,也就是说,让你的简单示例代码仍然运行(但我会听取建议,希望我是错的!-)。嗯。虽然你的解决方案像我要求的那样避免了泛型,但我想我宁愿让它使用泛型(甚至是混乱的)也不要在编译时捕获东西。我会自己研究一下,如果发现任何东西,我会发回。再次感谢!@incrediman,如果你想允许
ax=new B()
后面是
someb.foo(x)
(这在运行时类方面是非常正确的),即使泛型也没有帮助。好吧,我想我会坚持这一点-我找不到其他任何东西,尤其是在我的情况下,毫无疑问,在测试过程中肯定会发现误用。谢谢。