Extending an Inner class into a Nested class? - java

I was learning about Nested and Inner classes and this led me to think whether it is possible to extend an Inner class to be a Nested class or not. For example.
public class Outer{
public class Inner{
// notice the lack of static keyword
}
}
public class ExtendedOuter extends Outer{
public static class ExtendedInner extends Inner{
// notice the static keyword
}
}
I did try to compile the code above and I couldn't, but the compile time error I received made me believe that there may be a work around. I can however extend a Nested class to be an Inner class.
This is the compile time error I received.
no enclosing instance of type Outer is in scope

An inner class has a reference to the outer class. You cannot remove it in a subclass. This would be like removing a field in a sub-class.

Actually you can extend the inner class. You just have to provide an instance of Outer that the class will be bound to. To do so, you have to explicitly call the super constructor with the instance.
public class Outer {
public class Inner{
// notice the lack of static keyword
}
}
public class ExtendedOuter extends Outer {
private static Outer outer = new ExtendedOuter(); // or any other instance
public static class ExtendedInner extends Inner {
public ExtendedInner() {
outer.super(); // this call is explicitly required
}
}
}
This also works if you have a nested class that extends another nested class from a different enclosing class.

Your question doesn't make sense. An inner class is already a nested class, and so is any other class defined inside another one. Evidently you don't know what these words mean:
nested class: a class declared inside another one
inner class: a nested class that isn't declared 'static'.
Note that 'static nested' and 'inner' are mutually exclusive. Note also that an inner class can extend a static nested class, but not vice versa.
What your code is actually trying to do is extend the inner class as a static class, which is what causes the error. Not because the extending class is nested.

Related

how to access the outer class members in subclass wherin inner class is inherited

//below class is the example where in subclass extends the innerclass and from the subclass i am trying to access the methods of outer class i.e encapsulating class of inner class.
package innerClass;
public class outterclass {
private int outer=24;
protected int get_outer(){
return outer;
}
protected static class innerclass{
private int outer=25;
protected int get_outer(){
return outer;
}
}
}
package innerClass;
public class subclass_B extends outterclass.innerclass {
void parent_class_info_fetch(){
System.out.println(get_outer());
//i want to access the outer class get_outer method and how do i achieve that?
}
public static void main(String[] args) {
InheritanceStaticInnerClass_B isb=new InheritanceStaticInnerClass_B();
isb.parent_class_info_fetch();
}
}
Your innerclass is not an inner class. It is a static nested class and bears no special relationship to its enclosing class. You cannot reach an instance of the enclosing class because no such instance is available to innerclass or its subclasses.
If innerclass was indeed inner, then you would have to instantiate it with an enclosing instance:
outterclass outer = new outerclass();
subclass_B b = outer.new subclass_B();
Then, in parent_class_info_fetch() you could write
outterclass.this.get_outer()
to reach that method.
Of course, there would be several layers of bad practices in such code, so consider this just an academic execrise.
You should also learn about the basic naming conventions in Java.
The class outterclass.innerclass is a static class field, which means you don't necessarily have an enclosing instance of outterclass. On the other hand, the method get_outer of outterclass is an instance method, so you'll need the enclosing instance to call it.
With the class hierarchy you have, you'd have to make get_outer static (which requires making outer static as well).

In Java what is the relationship between a nested class and its outer class?

When a nested class in instantiated how does it reference the outer class? Does it always extend the outer class or reference it another way? I was told that the inner extends the outer but then why doesn't the following example work?
For Example:
public class OuterClass {
public String fruit = "apple";
public class InnerClass {
public String fruit = "banana";
public void printFruitName(){
System.out.println(this.fruit);
System.out.println(super.fruit);
}
}
}
The above does not compile with an error for super.fruit saying that 'fruit' cannot be resolved. However if the inner class is specified to extend the outer class then it works:
public class OuterClass {
public String fruit = "apple";
public class InnerClass extends OuterClass {
public String fruit = "banana";
public void printFruitName(){
System.out.println(this.fruit);
System.out.println(super.fruit);
}
}
}
This seems to show that the inner class does not extend the outer class unless specifically specified.
There is no implicit sub-type relationship: your observation/conclusion is correct. (In the first case, super has the type of "Object" and "Object.fruit" does indeed not exist.)
An inner class (as opposed to "static nested class"), as shown, must be created within context of an instance of the outer class; but this is orthogonal to sub-typing.
To access a member of the outer class, use OuterClass.this.member or, if member is not shadowed, just member will resolve; neither super.member nor this.member will resolve to the outer class member.
Extending the outer class "fixes" the compiler error, but the code with this.fruit doesn't access the member of the enclosing OuterClass instance - it simply accesses the member of the InnerClass instance inherited from the superclass it extends.

Are methods in static nested classes implicitly static?

Just looking for a confirmation.
public class Indeed{
public static class Inner implements Runnable{
public void run()
{
System.out.println("Indeed");
}
}
public static void main (String []args)
{
Indeed.Inner inner = new Indeed.Inner();
inner.run();
}
}
As you can see in the code above, I can declare public void run() without declaring it static. I guess it's implicitly done. Isn't it?
One more question related: Why I cannot use the method run as following: Indeed.Inner.run(); it is static after all, there should not be any need of instantiating the inner member at all? ( I know I am wrong as it does not compile if I do that, however I would like to know why).
Thanks in advance.
As you can see in the code above, I can declare public void run() without declaring it static. I guess it's implicitly done. Isn't it?
No.
One more question related: Why I cannot use the method run as following: Indeed.Inner.run();
Becuase it's not static.
static class is only valid for inner classes and you can point to a static class by its enclosing class as Indeed.Inner.
This is different from non-static inner class where you need an instance of the enclosing class to create an instance of the same class. For example:
Indeed.Inner inner = new Indeed().new Inner();
No, run() is an instance method of the static class Inner. A static (inner) class just makes it possible to use an instance of the class without an enclosing parent instance. When you do Indeed.Inner inner = new Indeed.Inner();, you are creating an instance of the static class, and you are invoking it's run() method on this instance.
A static class is just a regular class, in fact more so than a non-static class.
The difference between a static nested class and a top-level class is just access scoping: the static class can access private members of its enclosing class.
Once you get that cleared up, you won't need to ask the question that you are asking here.
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Non-static nested classes (inner classes) have access to other members of the enclosing class
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class.
Static inner class
public static class Inner implements Runnable
means you can create the instance of them, without having to create the instance of outer class (Indeed)
Indeed.Inner inner = new Indeed.Inner();
Why I cannot use the method run as following: Indeed.Inner.run() ?
the run method is by default not static. To call Indeed.Inner.run() directly, you need to make run() method static too

No enclosing instance of type PerfHelper is available due to some intermediate constructor invocation

Consider the below code:
class abstract Normal1 extends Something
{
}
class Outer
{
class abstract Inner extends Normal1
{
}
}
class General extends Outer.Inner // Problem occurs at this
{
}
The error I am getting is "No enclosing instance of type PerfHelper is available due to some intermediate constructor invocation"
My question is can I extend the inner class like above ?
Declare the inner class as static and you should be able to extend it:
class outer {
static abstract class inner extends normal1 { }
}
If inner is not abstract, it's tied to outer, and can only exist when an instance of outer exists. Check to see if this is what you really want.
Nested class are like(in sense ) Property of a class.
As in case of instance variable it only when available when its object is created as same as inner class also available when outer's object will created.
So if you want to extend this then make your inner class as static inner class
As jordao suggest above
Try this, (Read nested class inheritance rules).
abstract class normal1 extends something { }
class outer
{
abstract class inner extends normal1{}
}
class Outer1 extends outer
{
class General extends inner {}
}
In your class General modify its constructor a to call super inner class constructor. here is the code..
public General(){
new outer().super();
}

Referencing non static variable from within static Inner Class

I need to reference a variable of a top level class from a method within a static class.
This method should act on unique instances of the top level class and so it feels like I shouldn't instantiate the top level class inside the static class.
Basically I want something like
public class TopLevel{
// private
int innerV
public static class Inner implements X {
for(i=0; i<innerV,i++){
doSomething
}
}
}
Is it possible to just say this.innerV or something similar in the for loop and similar places?
From a static inner class, you can't refer to (nonstatic) members of the outer class directly. If you remove the static qualifier, it will work, because instances of nonstatic inner classes are implicitly tied to an instance of the containing class, so they can refer to its members directly.
Declaring your inner class static removes this link, so you need to either pass an instance of the outer class to the inner class method (or its constructor) as a parameter, or create it inside the method.
You can't do that. Create a TopLevel instance and if you make an innerV accessor (getter/setter) or make it public, than you can.
public class TopLevel {
public int innerV
public static class Inner implements X {
for(i=0; i<innerV,i++){
TopLevel tl = new TopLevel()
tl.innerV = 12345678;
}
}
}
You can't do that because it doesn't make sense, any more than referring to a non-static member from a static function makes sense. There is no current instance of the outer class in the context of the static inner class to get the instance variable from.

Categories

Resources