Jacob
Jacob

Reputation: 333

Scope Issue. How to reference method?

I have this scenario:

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

How can I call getIndex() in class C's body?

Upvotes: 0

Views: 45

Answers (4)

Dave Thomas
Dave Thomas

Reputation: 3837

Odd scenario... but you'd have to move class C to also be an inner class inside class A. Shrug? Curious why are you extending an inner class in the first place? What are the restrictions of the design that are causing this? Not judging you at all. Having the thinking behind the design could aide in possibly finding an alternative solution.

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();
      }

    }
}

Bonus research: For those that are maybe as curious as me and thought about using this to reference the function from another file. If you compile C in another file, and try accessing getIndex by using the enclosing this:

A.this.getIndex();

Sadly that won't work because even though C extends B, it still needs to be enclosed by A for that methodology to work. You get this compile time error:

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

Hey cool! another answer, based off @mzl's answer below: So interestingly enough, You can keep B static and extend both classes to get what you want to do. This is useful for example if you can not edit file A.java, because A.java is 3rd party functionality. (give @mzl credit here for his answer below)

Here is how you'd do it that way! ( Tested this compiles via 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();
         }

    }

 }

I've created a static over flow project proving @mzl's theory here: https://github.com/davethomas11/stackoverflow_Q_39441077

One gothcha. You'll notice I create an instance of C before D to make sure there is access to getIndex(). I haven't tested what happens if you instantiate D directly I will do that later and post the results.


Late update on that instantiate D directly test.

I added C.D testD = new C.D(); in my static main function:

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

The compiler helps us by not letting us do this.

Upvotes: 3

mzl
mzl

Reputation: 183

If you want to extend (non-statically) a inner class you must extend the outer class aswell.

You could do it this way:

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

Upvotes: 1

Little Santi
Little Santi

Reputation: 8803

(I feel it is an interesting theoretical question but with little meaning in practice.)

You can't event access A.getIndex from B because B is static, and getIndex is not, so to invoke getIndex you need a non-null instance of A.

Assuming you could make B non-static, you couldn't either, because your scheme becomes contradictory:

  • In one hand, class B is inner, so to instantiate a new object a previous non-null instance of A is required:
    A a=new A();
    B b=a.new B();
  • But in the other hand, class C is a top-level (not inner) class, so it may be directly instantiated. However, being a subclass of B, it is subject to the same restrictions as its superclass: It needs an instance of A. Contradictory!

The only way I think to make it work is to declare getIndex static, so no instance of A would be needed (in fact, neither subclassing from B would be a problem).

Upvotes: 0

nhouser9
nhouser9

Reputation: 6780

You can't. C extends B which does not have a getIndex() method. C must extend A to inherit that method.

Upvotes: 0

Related Questions