Why can't I do this/is there a workaround to accomplish this:
package myPackage;
public class A {
public class B {
}
}
package myPackage;
import myPackage.A.B;
public class C extends B {
}
package myPackage;
public class Main {
public static void main(String[] args) {
A myA = new A();
C myC = myA.new C();
}
}
The two compilation errors are
On
public class C extends B
,No enclosing instance of type A is available due to some intermediate constructor invocation
On
C myC = myA.new C();
,A.C cannot be resolved to a type
Frankly, I think the conceptual idea is sound: I want to make a subclass of B so that when I make a B for A, I have the option of making it have the functionality in B or the functionality in C.
Four workarounds/solutions that I don't want, and why I don't want them:
"Solution: Put C inside of A." I don't want this because what if I can't modify the code for A.java (there are applications that have this restriction)? What if A is part of another API? Then I have to create a new file for C, as I've done here.
"Solution: Put C inside of a class D that extends A." I don't want this because then C is restricted to only being instantiated on instances of type D. I want to make a class that extends B that can be instantiated on all instances of type A (there are applications that need this). Therefore, I need C to not be enclosed by another class, as I've done here.
(Added as a question edit - see JoshuaTaylor's answer for a code sample) "Solution: Make B static." I don't want this because what if functionality in B needs to access its enclosing instance of A (there are applications that need this)? Therefore, I need B to not be static, as I've done here. (2nd question edit: You could make B static and have its constructor take in its enclosing instance, saving it in a protected variable for access in its children, but this is less elegant than the accepted answer by RealSkeptic)
Removed. See edit at bottom.
So, if your answer suggests that I do one of the above, it is not an answer to this question, even though it might be useful for other people.
If your answer is "This is just a flaw of the Java language, you simply can't accomplish that conceptual idea", that is an okay answer, and you should post it. Just a warning though: I will hold off on marking your answer as accepted in case you are wrong. If this is your answer, I would highly appreciate if you have an explanation for why this restriction on the language is in place (as that's the title of this question).
Thank you for any and all help.
EDIT: JoshuaTaylor's answer brings up a valid option: you can extend B anonymously and avoid having to write a constructor as in RealSkeptic's accepted answer. I originally discarded this idea because it does not allow you to access C's enclosing instance of A via "A.this". However, I have since learned that C does not have an enclosing instance of A unless it is specifically defined within the definition of A as a nested class. So please note: none of the solutions below allow you to access the enclosing instance of A that encloses C's ancestor of B via writing "A.this" in a method of C. Classes can only use ".this" to access types which they are specifically nested in. However, if B has functionality that accesses the enclosing instance of A, either an anonymous class via JoshuaTaylor's method or any other class via RealSkeptic's method is required.
public static class B
), can you do what you're trying to do? – Maniple