Java Inner Class extends Outer Class

amaidment picture amaidment · Aug 19, 2011 · Viewed 15k times · Source

There are some cases in Java where an inner class extends an outer class.

For example, java.awt.geom.Arc2D.Float is an inner class of java.awt.geom.Arc2D, and also extends Arc2D. (c.f. http://download.oracle.com/javase/6/docs/api/java/awt/geom/Arc2D.Float.html)

Also, sun.org.mozilla.javascript.internal.FunctionNode.Jump extends sun.org.mozilla.javascript.internal.Node, which is a superclass of FunctionNode. (sorry... cannot find a link to the javadoc)

To me, this seems odd. Could you then create these?

new Arc2D.Float.Float() //n.b. I couldn't get this to compile in Intellij IDEA;

new FunctionNode.Jump.Jump.Jump(1); // I could get this to compile

What purpose does it serve to have a subclass nested as an inner class of the superclass?

I wondered whether it was to access something in the superclass, but if you wanted to access any variables/methods in the parent, you could use

super.variable;

or

super.method();

Edit 1: jjnguy has suggested it's to keep the logic in the same place. In which case, why wouldn't you write a file com.mypackage.AbstractTest:

abstract class AbstractTest {
  abstract String getString();
}

class ExtensionTest extends AbstractTest {
  @Override
  String getString() {
    return "hello world";
  }
}

... rather than:

abstract class AbstractTest {
  abstract String getString();

  class ExtensionTest extends AbstractTest {
    @Override
    String getString() {
      return "hello world";
    }
  }
}

Edit 2: It has rightly been pointed out that the suggestion in my previous edit was flawed, as couldn't construct ExtensionTest outside of the package. However, I've had a further think about this over the weekend, so what about the following:

abstract class Test {
  public class ExtensionTest extends AbstractTest {
    @Override
    String getString() {
      return "hello world";
    }
  }

  private abstract class AbstractTest {
    abstract String getString();
  }
} 

In essence, the best answer I've seen so far is that having an inner class extend its outer class allows the logic to be grouped together. However, I think that this can be done without the extension.

In my mind, it seems like bad design to have a class that can have an infinite number of the same subclasses nested within it. (Context: this came up whilst trying to produce a dictionary for a code completion utility, and threw a StackOverflowException. I found a workaround, but I just cannot understand why it had been designed that way.)

Answer

jjnguy picture jjnguy · Aug 19, 2011

Have a look at Java's Point2D. It has two inner classes that are sub-classes of it.

The important thing to note is that they are static inner classes. This has an entirely diffenent meaning that a regular inner class. Just like a static method, a static class is defined at the class-level instead of the object level.

In the Point2D case, it is done to logically couple the classes and their logic. It helps a user of the abstract type Point2D find an implementation that they can use.

In response to your edit I'd like to point out 1 important fact. A single Java file may only contain one public class, except for public inner classes. While both of your examples may compile, they do not allow access to those classes to the public. If you want to present multiple public classes to someone in a single file, you must use public static inner classes.