范围问题。如何参考方法?

时间:2016-09-11 21:57:13

标签: java

我有这种情况:

public class A
{
  private final Integer index;

  public Integer getIndex() { return index; }

  public static class B
  {
    //unimportant
  }
}

public class C extends B
{
  //how to reference getIndex() here?
}

如何在C类的主体中调用getIndex()?

4 个答案:

答案 0 :(得分:3)

奇怪的场景......但你必须将C级移动到A级内部的类内部。耸肩?好奇为什么你要扩大一个内部阶级?造成这种情况的设计有哪些限制?根本没有评判你。了解设计背后的想法可能有助于找到替代解决方案。

public class A
{
   // make sure final value is set here or in constructor
   private final Integer index = 0;

   public Integer getIndex() { return index; }

   public static class B
   {
      //unimportant
   }

   //Doesn't make much sense... but...
   public class C extends B
   {

      //can now call getIndex()
      public void callGetIndex() {
         getIndex();
      }

    }
}

奖金研究: 对于那些可能像我一样好奇的人,并考虑使用它来引用另一个文件中的函数。如果您在另一个文件中编译C,并尝试使用封闭的来访问getIndex:

A.this.getIndex();

可悲的是,这不起作用,因为即使C扩展了B,它仍然需要被A包围才能使该方法起作用。您收到此编译时错误:

C.java:5: error: not an enclosing class: A
        A.this.getIndex();
         ^
1 error

嘿酷!另一个答案,基于@ mzl的答案: 有趣的是,你可以保持B静态并扩展两个类以获得你想要做的事情。例如,如果您无法编辑文件A.java,这很有用,因为A.java是第三方功能。 (在这里给@mzl提供他的回答)

以下是你如何做到这一点! (通过javac A.java C.java测试此编译)

<强> A.java

public class A
{
  private final Integer index = 0;

  public Integer getIndex() { return index; }

  public static class B
  {
    //unimportant
  }

}

C.java

public class C extends A
{

    public class D extends A.B {
        //can now call getIndex()
         public void callGetIndex() {
            getIndex();
         }

    }

 }

我创建了一个静态溢流项目,证明了@ mzl的理论: https://github.com/davethomas11/stackoverflow_Q_39441077

一个哥特式。您会注意到我在D之前创建了一个C实例,以确保可以访问getIndex()。我没有测试如果直接实例化D会发生什么,我会稍后再这样做并发布结果。

该实例化D的后期更新直接测试。

我在静态主函数中添加了C.D testD = new C.D();

$ sh build.sh
StackOverflowQuestion39441077.java:5: error: an enclosing instance that contains C.D is required
        C.D testD = new C.D();
                    ^
1 error

编译器帮助我们不要让我们这样做。

答案 1 :(得分:1)

如果你想扩展(非静态地)内部类,你必须扩展外部类。

你可以这样做:

public class A
{
    private final Integer index;

    public Integer getIndex() { return index; }

    public static class B {}
}

public class D extends A{

    public class C extends B{}
}

答案 2 :(得分:0)

你做不到。 C扩展了B,但没有getIndex()方法。 C必须扩展A才能继承该方法。

答案 3 :(得分:0)

(我觉得这是一个有趣的理论问题,但在实践中没什么意义。)

A.getIndex您无法访问B,因为B是静态的,getIndex不是,所以要调用您需要的getIndex A的非空实例。

假设你可以使B非静态,你也不能,因为你的方案变得矛盾:

  • 一方面,类B是内部的,因此要实例化一个新对象,需要先前的A非空实例:
    A a=new A();
    B b=a.new B();
  • 但另一方面,类C是顶级(非内部)类,因此可以直接实例化。但是,作为B的子类,它受到与其超类相同的限制:它需要A的实例。矛盾!

我认为让它发挥作用的唯一方法是声明getIndex 静态,因此不需要A的实例(事实上,它们都不是{{}}的子类化1}}会有问题。)