简体   繁体   中英

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

If I have the following class:

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

I can obviously instantiate the object, and I know some sort of subclassing must be going on since I can override the Hooray method, but if there's subclassing, why can't I create a new method inside the anonymous class?

TestObject a = new TestObject() {
    public String Boo() {
        return "Booooo";
    }
};

System.out.println(a.Boo());

returns a syntax error

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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