I know I can access methods of outer class from within the inner class.
Like the below class:
class outer {
void outerMethod() {}
class inner {
void innerMethod() {
outerMethod();
}
}
}
I want to know how can I do this if I extended the inner class?
I want to do the following:
class newClass extends outer.inner {
void innerMethod() {
outerMethod();
}
}
I want to be able to access method() from newClass
Instance of non-static inner class requires existence of outer class instance which it will belong to.
So to make class newClass extends outer.inner { compile you either need to
make inner class static, and remove requirement of existence of outer class instance (but this will also limit your class a little)
or ensure that inner will belong to some outer instance, which you can do by calling outerInstance.super() inside your constructor of your class which extends this inner class.
In case of option 2, probably simplest solution would be explicitly passing instance of outer to your class like
class newClass extends outer.inner {
private outer o;
public newClass(outer outerInstance) {
outerInstance.super();
this.o = outerInstance;
}
void innerMethod() {
o.outerMethod();
}
}
Now you can simply call your outerMethod() on passed instance of outer class.
But remember that calling outerMethod is possible only when this method has proper visibility for your newClass. So despite the fact that inner is able to use any method of its outer class your newClass may not have access to it.
Related
jdk version:1.8.0_241
There is a class extending a inner class. Code as follows:
class WithInner {
class Inner {
}
}
public class ExtendInnerClass extends WithInner.Inner {
ExtendInnerClass(WithInner withInner) {
withInner.super();
}
}
To connect WithInner class's object and Inner class's object, we have to use super() method.
But when i decompiled the class file, i find something interesting.
public class ExtendInnerClass extends Inner {
ExtendInnerClass(WithInner withInner) {
withInner.getClass();
super(withInner);
}
}
I find that compiler not only use super() method but also withInner.getClass().
why he do this?
An inner class object usually need to hold a reference to its outer class object.
Inner class has loaded before outer class without getClass(), it doesn't meet the principle of jvm, so use getclass() to load outer class in jvm before inner one.
//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).
Let's say I have class like this:
class Outer {
public void getOuterValue() { }
class Inner {
public void getInnerValue() { }
}
}
I understand that I could create an object of this class as:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
But let's suppose I am getting this object from some other method:
void someMethodSomewhere(Outer o) {
// How do I call getInnerValue() here using o?
}
Is there a way to call "getInnerValue" method using "o" in the scenario above?
Please let me know.
No. You need to have an instance of Inner to call methods on it.
An instance of the outer class is not enough (it would work the other way around: the inner class instance has a reference to the outer class instance).
void someMethodSomewhere(Outer o) {
// How do I call getInnerValue() here using o?
}
You can't. getInnerValue() is a method in Inner. Outer is not an Inner and does not have a reference to an Inner. When you are handed o, there is no way to navigate from that to any instance of Inner because there isn't one associated with o.
I know that if I want to extend inner class I should make something like this:
class Outer{
class Inner{}
}
class My extends Outer.Inner{
My(Outer outer){
outer.super();
}
}
But at this situation I don't understand how should I do? how to get enclosing instance of inner object?
class My extends Outer.Inner{
My(Inner inner){
// how to get enclosing instance of inner here
}
}
this variant doesn't compile:
class Outer{
class Inner{}
}
class My extends Outer.Inner{
My(Outer.Inner inner){
inner.Outer.this.super();
}
}
If I understand you correctly, you want to access members of the outer class from the class extending the inner class.
You can only do this depending on the scope in which you declare your class. When you extend the inner class inside the outer class, all members are in scope and you can access them, something like
class Outer {
private int var = 0;
class Inner {}
class My extends Outer.Inner {
My() {
var = 1;
}
}
}
If you declare the class outside the outer class, you can still access package private members if the extending type is in the same package
class Outer {
int var = 0;
class Inner {}
}
class My extends Outer.Inner {
My( Outer outer ) {
outer.super();
outer.var = 1;
}
}
If you're outside package scope, you might solve this by enclosing your class inheriting the inner class in a class inheriting the outer class to get access to its protected members:
class Outer {
protected int var = 0;
class Inner {}
}
class OuterMy extends Outer {
class My extends Inner {
My( Outer outer ) {
var = 1;
}
}
}
If that isn't an option either, you only get access to the public members by storing the outer instance manually.
class Outer {
public int var = 0;
class Inner {}
}
class My extends Outer.Inner {
private Outer outer;
My( Outer outer ) {
outer.super();
this.outer = outer;
}
void method() {
outer.var = 1;
}
}
As far as I know those are your options, you cannot access the JVMs internal instance of the enclosing class
I believe this works if you make the inner class static.
That way, you can create an instance of the inner class even without the outer class.
A non static inner class has an implicit pointer to the containing class (Outer.this). So you cannot create it outside of the outer class. But the following works fine :
class Outer{
class Inner{}
class My extends Inner{
My(Inner inner){
//You cannot access Outer.this outside the object itself
//inner.Outer.this.super();
}
}
}
If the inner class is declared static it has no implicit pointer and the above limitation no longer applies.
An inner class is just a normal class with a hidden field that holds a reference to the outer class instance that was used to create it.
You have correctly created a sub-class to override the inner class, so that sub-class is Inner. There will be no other "enclosing instance of inner object". You have this.
To access Outer from My, you'll have to either save it to another field in My or make a method in Inner to expose it because the field Outer.this is referring to is private.
I have found only one solution:
class Outer{
class Inner{
Outer outer = Outer.this;
}
}
class My extends Outer.Inner{
My(Outer.Inner inner){
inner.outer.super();
}
}
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();
}