Why can't I create a new method in an anonymous inner class?

后端 未结 3 936
余生分开走
余生分开走 2021-01-28 10:25

If I have the following class:

public class TestObject {
  public String Hooray() {
    return \"Hooray!\";
  }
}

I can obviously instantiate t

相关标签:
3条回答
  • 2021-01-28 10:46

    You can create the method, there's nothing wrong with your Boo method (apart from the fact that it has a capital letter at the front). The problem is that outside of the anonymous class, the Boo method is not available (it is not exposed as part of the API of the class).

    This is the same with any class that implements an interface... if the class has methods (even public methods) that are not part of the interface then you need to cast the instance to the specific class in order to access these methods.

    Unfortunately, because this is an anonymous class, you can't cast it (you don't know what to cast it to).

    These internal methods can still be useful, but you have to call them from inside the anonymous class, not from outside.

    0 讨论(0)
  • 2021-01-28 11:00

    Because the class has no name, you cannot refer to its type definition at compile time. The compiler can only know it as a TestObject, which has no boo() method

    0 讨论(0)
  • 2021-01-28 11:01

    You have this:

    public class TestObject {
      public String Hooray() {
        return "Hooray!";
      }
    }
    
    TestObject a = new TestObject() {
        public String Boo() {
            return "Booooo";
        }
    }
    
    System.out.println(a.Boo());
    

    You can't do this. You can create new methods in anonymous inner classes, and, in fact, you are. But you wouldn't be able to call a.Boo() from outside, since a is a TestObject and TestObject has no method named Boo. It's the same reason you can't do this:

    public class Base {
        public void something (); 
    }
    
    public class Derived extends Base {
        public void another ();
    }
    
    Base b = new Derived();
    b.another(); // b is a Base, it must be cast to a Derived to call another().
    

    In the above you have to cast b to a Derived to call the new method added to the derived class:

    ((Derived)b).another();
    

    The reason that you couldn't do this with anonymous inner classes (which are just syntactic shortcuts for deriving new subclasses) is precisely because they are anonymous - there is no type available for you to cast them to.

    The reason you can't access another() through type Base, by the way, is pretty simple when you think about it. While Derived is a Base, the compiler has no way of knowing that Base b is holding a Derived as opposed to some other subclass of Base that doesn't have an another() method.

    Hope that helps.

    0 讨论(0)
提交回复
热议问题