如何访问基类方法?

时间:2018-05-02 14:25:28

标签: java class

简化演示代码以显示我的问题。

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"
  } 

};

我尝试了强制转换方法(test1)和辅助方法(test2)。

到目前为止,我发现需要Base的复制构造函数来创建一个真正的Base对象。

是否有一个不需要重复对象的方法?

一些背景信息:

我得到一个A的实例,我知道它的基类有一个很好的方法,我想用它来代替覆盖的版本。我更喜欢既不修改A类也不修改B类(尽管副本c' tor无论如何都是一个很好的增强;)

2 个答案:

答案 0 :(得分:7)

直接从课程A,您可以super.toString();使用toString()Base上执行A

但是,从外部类A开始,您无法以这种方式调用超类实现,这样做会破坏封装。如果你想暴露超类实现,那么你仍然可以,但你必须在System.out.println(Base.class.getMethod("toString", null).invoke(new A(), null)); //Prints "A" 上提供一个直接公开它的单独方法。

即使使用基于琐碎反射的方法,you still won't be able to access it:

  

如果底层方法是实例方法,则使用动态方法查找

调用它
MethodHandles.lookup().findSpecial

...并且使用IllegalAccessException将无法在子类外部工作,因为必须在您具有私有访问权限的情况下调用它(否则您将获得-core。)

我承认,如果没有字节码操作,我可能会直接在Java中使用一些奇怪且奇妙的方式来做这件事,但即使你可以,也可以说这样做,除了古怪的技术演示之外,你当然不应该

答案 1 :(得分:3)

你需要创建B实例(复制构造函数),如果你正在使用A实例,你总会得到" A"无论你是否投了它。