Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing Inner Class from Outer Class versus other Inner Class

I am befuddled why this is allowed

public class Foo {
    class Bar extends Foo {
    }
}

Yet this is not allowed

public class Foo {
    class Bar extends Foo {
    }

    class Fooey extends Bar {
    }
}

The compiler informed that it can not reference Fooey.this before supertype constructor has been called.

And this is allowed

public class Foo {
    static class Bar extends Foo {
    }

    class Fooey extends Bar {
    }
}

What is going on here? And where can I go to find more information on how inner class inheritance works?

EDIT I came upon both rather poor ideas; inner class extends outer class and inner class extends other static inner class. I wasn't sure what exactly was going and how I should refactor this. I ended up just yanking out the inner classes and encapsulating them in the outer class.

like image 922
sal Avatar asked Oct 19 '09 15:10

sal


People also ask

Can we access inner class from outer class or classes from another package?

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

How do you call an inner class from another class?

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass. InnerClass innerObject = outerObject.

Is there any difference between an inner class and nested class?

A class that is defined within another class is called a nested class. An inner class, on the other hand, is a non-static type, a particular specimen of a nested class.

Can an inner class be accessed from outside package?

Unlike a class, an inner class can be private and once you declare an inner class private, it cannot be accessed from an object outside the class.


3 Answers

First of all: Don't do this sort of thing. It's evil. Really, Java 1.1 should have been specified very much more restrictively, IMO.

There is confusion about which this to use from the Foo.Fooey constructor. The outer this (Foo.this) would work. But the actual this is a Foo but it can't be passed to the superconstructor because of rules about using this before the superconstructor returns (and besides having an outer instance the same instance as the inner instance is fecked up). The outer this on the superclass "((Bar)this).this$0" (IIRC), is also inaccessible due to restrictions on use of this.

The solution is to be explicit. Explicit is usually a good thing in my book (unless it becomes boilerplate).

public class Foo {
    class Bar extends Foo {

    }

    class Fooey extends Bar {
        Fooey() {
            Foo.this.super();
        }
    }
}

Better yet, don't have an inner class extend its own outer class, or extend any inner class.

like image 123
Tom Hawtin - tackline Avatar answered Oct 19 '22 23:10

Tom Hawtin - tackline


I guess the JLS and the answers to this question are a starting point

Java inner class and static nested class

Inner Classes and Enclosing Instances

like image 27
jitter Avatar answered Oct 20 '22 01:10

jitter


Tom Hawtin answer is correct.

Have also a look at java puzzler. The sample chapter contains this case and a few other "interesting" case you may want to have a look at.

like image 22
vdr Avatar answered Oct 20 '22 01:10

vdr