简化演示代码以显示我的问题.
class Base {
public String toString() { return "Base"; }
};
class A extends Base {
public String toString() { return "A"; }
};
class Test {
public void test1() {
A a = new A();
Base b = (Base)a; // cast is fine, but b is the same instance as a
System.out.println(b.toString()); // want "Base", but get "A"
}
private String testB(Base b) {
return b.toString(); // this should return "Base"
}
public void test2() {
System.out.println( testB(new A()) ); // want "Base", but get "A"
}
};
Run Code Online (Sandbox Code Playgroud)
我尝试了强制转换方法(test1)和辅助方法(test2).
到目前为止,我发现需要Base的复制构造函数来创建一个真正的Base对象.
有没有一个不需要重复对象的方法?
一些背景信息:
我得到一个A的实例,我知道它的基类有一个很好的方法,我想使用它而不是覆盖的版本.我宁愿既不修改A类也不修B(虽然副本c'tor无论如何都是一个很好的增强;))
从类A直接,你可以使用super.toString();来执行toString()的Base.
但是,从外部类中A,您无法以这种方式调用超类实现,这样做会破坏封装.如果你想暴露超类实现,那么你仍然可以,但你必须提供一个单独的方法A直接公开它.
即使使用基于琐碎反射的方法,您仍然无法访问它:
如果底层方法是实例方法,则使用动态方法查找调用它
System.out.println(Base.class.getMethod("toString", null).invoke(new A(), null)); //Prints "A"
Run Code Online (Sandbox Code Playgroud)
...并且使用MethodHandles.lookup().findSpecial将无法在子类外部工作,因为必须在您拥有私有访问权限时调用(否则您将获得一个IllegalAccessException.)
我承认,如果没有字节码操作,我可能会直接在Java中使用一些奇怪而奇妙的方法,但是,即使你可以这样做,你也应该说,你当然不应该做任何事情.奇特的技术演示.