16

In the example below, how can I access, from C, the method method() of the class A?

class A {
    public void method() { }
}

class B extends A{
    public void method() { }
}

class C extends B{
    public void method() { }

    void test() {
        method();          // C.method()
        super.method();    // B.method()
        C.super.method();  // B.method()
        B.super.method();  // ERROR <- What I want to know
    }
}

The error I am getting is

No enclosing instance of the type B is accessible in scope

Answer: No, this is not possible. Java doesn't allow it. Similar question.

Community
  • 1
  • 1
John Assymptoth
  • 8,227
  • 12
  • 49
  • 68

4 Answers4

20

You can't - and very deliberately. It would violate encapsulation. You'd be skipping whatever B.method wants to do - possibly validating arguments (assuming there were any), enforcing invariants etc.

How could you expect B to keep a consistent view of its world if any derived class can just skip whatever behaviour it's defined?

If the behaviour B provides isn't appropriate for C, it shouldn't extend it. Don't try to abuse inheritance like this.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 5
    It's not about whether I should or not. I wanted to know if it is possible, that's all. But I see it isn't. – John Assymptoth Jan 15 '11 at 08:49
  • 6
    It's not the language's job to prevent me from doing my job (working around bugs in other code that we can't get fixed). – Glenn Maynard Apr 22 '13 at 23:59
  • 9
    @GlennMaynard: Then I suggest you change language - maybe to one with no restrictions at all... no concept of private vs public, no notion of encapsulation. Any restriction is bound to have times where it makes things more difficult - but the overall effect is positive. – Jon Skeet Apr 23 '13 at 05:55
11

Following code could be a work-around (not nice, but should work):

class A {
    public void method() { }
}

class B extends A {
    public void method() { }
    protected void superMethod() {
         super.method();
    }
}

class C extends B {
    public void method() { }

    void test() {
        method();          // C.method()
        super.method();    // B.method()
        superMethod();     // A.method()
    }
}
Mot
  • 28,248
  • 23
  • 84
  • 121
2

Well, there is no direct way of doing this but you can always try workarounds.

I am not sure of the purpose of accessing method in class A from class C but you can always get hold of that method.

You could either create an instance of class A in class C and if that looks too simple, try using reflection API... [link text][1]

Extreme Java

Sandeep
  • 21
  • 1
1

You shouldn't.

If you want to access the methods in A, extend from A instead of B.

When B extends A, it assumes that the underlying A-object won't be manipulated in other ways than how it does it itself. Therefore, by directly accessing the methods of A, you could be breaking how B functions.

Imagine, for instance, you have a class that implements a list, MyList. Now, imagine we extend this list with another class called MyCountingList, which overrides the add() and remove() methods to count the elements being added/removed. If you bypass the add() method MyCountingList provides, using the one MyList has instead, you've now broken the counting feature of MyCountingList.

So, in short, just don't.

Sebastian Paaske Tørholm
  • 49,493
  • 11
  • 100
  • 118