繁体   English   中英

使用子类中的重写方法

[英]Use overridden method from subclass

我有A班:

private static class A 
{
  public void foo() 
  {
    Sub sub = new Sub();
    sub.bar();
  }

  protected class Sub 
  {
    protected void bar() 
    {
      System.out.println("bar from A");
    }
  }
}

我想扩展它以对其子类Sub bar()稍加修改。

private static class B extends A 
{
  protected class Sub extends A.Sub 
  {
    @Override
    protected void bar() 
    {
      System.out.println("bar from B");
    }
  }
}

如果我现在打电话给我

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

从A获得酒吧 ,但我从B获得酒吧

我也可以解决覆盖foo()的问题。 但是foo()是一个巨大的方法,如果我简单地复制它,我将得到冗余代码。 我不能将其拆分成多个较小的。

有没有一种方法可以在不覆盖foo()情况下调用新的bar() foo()

A.foo()您将创建A.Sub的实例。 这就是为什么bar()A.Sub被调用,而不是bar()B.Sub

一种可能的解决方案是更换

Sub sub = new Sub();

与:

Sub sub = getSub();

然后在A:

protected Sub getSub()
{
    return new Sub();
}

在B中:

@Override
protected Sub getSub()
{
    return new Sub();
}

B的实例将产生B.Sub的实例,而A的实例将产生A.Sub的实例。

您正在为Java语言的一个相当尴尬的概念( 称为“阴影”)而苦苦挣扎。 您知道通过B extends A ,您将重写B中也定义的A所有非私有实例方法。 相反,您可能知道字段没有被覆盖。 如果定义在两个同名的场AB ,存在两个领域,其中在子场B 阴影在超类领域的A ,而无需更换其使用A

内部类也是如此。 这意味着A.SubB.Sub是两个不同的类,就像两个(假设的)字段A.fooB.foo是不同的一样。 A.Sub仅由B.Sub 因此,在A定义此调用时,调用new Sub()将创建A.Sub的实例, B.SubB定义时将创建A.Sub的实例。 为了模拟多态性,您需要以某种方式获取涉及的方法调用,以触发Java的动态调度。 有两种方法可以做到这一点:

  1. 定义一个工厂方法,您可以重写该方法来创建所需的实例:

     class A { class Sub { void doSomething() { System.out.println("A.Sub"); } } Sub make() { return new Sub(); } // Returns B.Sub } class B extends A { class Sub extends A.Sub { // Shadows A.Sub void doSomething() { System.out.println("B.Sub"); } @Override Sub make() { return new Sub(); } // Returns B.Sub, also when called within A } 
  2. 使A.SubB.Sub层次结构是多态的:

     class A { class Sub { void invoke() { doSomething(); } // Invokes outer method virtually } void doSomething() { System.out.println("A"); } } class B extends A { class Sub extends A.Sub { } // Shadows A.Sub @Override void doSomething() { System.out.println("B"); } } 

您需要在对象中注入Sub来实现这一点。 如果让它位于类A构造函数中,则它仅对A.Sub具有可见性。

然后,为A构造A接受A.Sub和子类的构造函数:

public A(Sub sub) {
  this.sub = sub;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM