Defining inner class outside java file - java

I want to create a class, ClassB, as inner class of ClassA, but I want to write down outside ClassA.java file.
How can I do this?
It will be a lot of inner class, and ClassA.java file will be enormous.
UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
Thanks.

The simple answer, is no you cannot.
By virtue of being an inner class, the class has to be inside the scope of the parent class.
If your class is really going to be enormous, it probably says something about the design of your class. Are you making proper use of encapsulation?

Put all your classes in a package and define the classes to be package private.
package com.example.here
class Hello{
//...
}
Notice the absence of the keyword public? You will only be able to create an instance of the class Hello if the class creating it is in the com.example.here package.

Try the following ...
Hand over a reference of the outer-class to the no-longer-inner-class
Use packages and make the no-longer-inner-class package-private (Jeremy's answer)
In the very rarest of cases, it might actually be best to go with inner classes, and at the same time have them do work elsewhere. If this really is you, please read on ...
How to keep inner classes small
a) Extend from outer classes
class Outer {
class SomeInnerClass extends SomeClass {
// More specific code here
}
}
class SomeClass {
// A lot of generic code here (in a different file)
}
b) Use abstract methods
One of the (more correct) reasons for using inner classes, usually has to do with the use of the exact instance of the outer-class. To tackle it in a generic fashion in the base class, use abstract getters.
abstract class SomeClass {
protected abstract SpecificData getSpecificData();
void someMethod() {
SpecificData specificData = getSpecificData();
// Do work with the "specific data" here ...
}
}
class Outer {
private SpecificData mSpecificData = new SpecificData();
class SomeInnerClass extends SomeClass {
#Override
protected SpecificData getSpecificData() {
return OuterClass.mSpecificData;
}
}
}
I think you get the idea, ... You might also consider using some GeneralData class or interface (within SomeClass) instead, and have getSpecificData() return a more specific (descended-)instance of it.
Again: This can be terribly misused to create very bad unreadable code, but it also can be used for very nice patters under the right circumstances, anyways it should answer the original question.

UPDATE
What I really want to do is define ten classes that they will be only accessible by one class. All of them are defined inside the same package.
If you want to restrict access to a single class, you can put them all in a new package. You will need to move the designated class that is allowed access into this packate, too. For the new classes, you can restrict access by using the default access level (no public/private/protected modifier). This will make them accessible only to the classes in their package. The specified class that is allowed access can be made public so that it can be used outside this new package.
Note: You have the option of restricting the visibility of the class or the visibility of the constructor.

Related

Is there a way to define a class as belonging inside a class from another file

Consider this example:
//OuterClass.java
class OuterClass
{
class InnerClass
{
Object parent()
{
return OuterClass.this;
}
}
}
Simple enough. InnerClass is created inside ("has an enclosing instance of") OuterClass, and has access to it.
Now, my problem is that in my case, OuterClass is BIG, and has multiple "inner classes".
As such, I would like to try to split all of this into multiple files.
Is there a way to tell a class that it "belongs into" another class?
Something in the likes of:
//OuterClass.java
class OuterClass
{
class InnerClass definedIn InnerClass.java;
}
//InnerClass.java
class InnerClass needsEnclosingInstanceOf OuterClass
{
Object parent()
{
return OuterClass.this;
}
}
or is the only way really just to make a constructor that needs an instance of the class, and access the class through that object?
A class and its inner classes must be in the same Java source file. There is no good way around this.
I guess you could feed your source code through some kind of pre-processor to assemble the real Java source file from a bunch of component files. But that will raise a bunch of other problems1. So is it (IMO) not something that is worth pursuing.
My advice: either put up with the unpleasantly large source file, or split it into separate classes in separate files.
Note that inner classes are actually a form of syntactic sugar. At the implementation level, the inner classes' constructor is passed a hidden extra parameter which is a reference to an instance of the outer class. You can do the same thing explicitly to get equivalent behavior without class nesting.
1 - For instance, it will break your IDE ... unless the IDE understands the syntax and semantics of the hypothetical preprocessor.

Why private members of nested class are accessible in outer class [duplicate]

I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:
class ABC{
class XYZ{
private int x=10;
}
public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}
Why is this behavior allowed?
The inner class is just a way to cleanly separate some functionality that really belongs to the original outer class. They are intended to be used when you have 2 requirements:
Some piece of functionality in your outer class would be most clear if it was implemented in a separate class.
Even though it's in a separate class, the functionality is very closely tied to way that the outer class works.
Given these requirements, inner classes have full access to their outer class. Since they're basically a member of the outer class, it makes sense that they have access to methods and attributes of the outer class -- including privates.
If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow:
class ABC{
private interface MyInterface{
void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.
The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.
There's a correct answer appearing on another question similar to this:
Why can the private member of an nested class be accessed by the methods of the enclosing class?
It says there's a definition of private scoping on JLS - Determining Accessibility:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Thilo added a good answer for your first question "How is this possible?". I wish to elaborate a bit on the second asked question: Why is this behavior allowed?
For starters, let's just be perfectly clear that this behavior is not limited to inner classes, which by definition are non-static nested types. This behavior is allowed for all nested types, including nested enums and interfaces which must be static and cannot have an enclosing instance. Basically, the model is a simplification down to the following statement: Nested code have full access to enclosing code - and vice versa.
So, why then? I think an example illustrate the point better.
Think of your body and your brain. If you inject heroin into your arm, your brain gets high. If the amygdala region of your brain see what he believe is a threat to your personally safety, say a wasp for example, he'll make your body turn the other way around and run for the hills without You "thinking" twice about it.
So, the brain is an intrinsic part of the body - and strangely enough, the other way around too. Using access control between such closely related entities forfeit their claim of relationship. If you do need access control, then you need to separate the classes more into truly distinct units. Until then, they are the same unit. A driving example for further studies would be to look at how a Java Iterator usually is implemented.
Unlimited access from enclosing code to nested code makes it, for the most part, rather useless to add access modifiers to fields and methods of a nested type. Doing so is adding clutter and might provide a false sense of safety for new comers of the Java programming language.
An IMHO important use case for inner classes is the factory pattern.
The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.
In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...
class MyPrivates {
static class Inner1 { private int test1 = 2; }
static class Inner2 { private int test2 = new Inner1().test1; }
public static void main(String[] args) {
System.out.println("Inner : "+new Inner2().test2);
}
}
Access restrictions are done on a per class basis. There is no way for a method declared in a class to not be able to access all of the instance/class members. It this stands to reason that inner classes also have unfettered access to the members of the outer class, and the outer class has unfettered access to the members of the inner class.
By putting a class inside another class you are making it tightly tied to the implementation, and anything that is part of the implementation should have access to the other parts.
The logic behind inner classes is that if you create an inner class in an outer class, that's because they will need to share a few things, and thus it makes sense for them to be able to have more flexibility than "regular" classes have.
If, in your case, it makes no sense for the classes to be able to see each other's inner workings - which basically means that the inner class could simply have been made a regular class, you can declare the inner class as static class XYZ. Using static will mean they will not share state (and, for example new ABC().new XYZ() won't work, and you will need to use new ABC.XYZ().
But, if that's the case, you should think about whether XYZ should really be an inner class and that maybe it deserves its own file. Sometimes it makes sense to create a static inner class (for example, if you need a small class that implements an interface your outer class is using, and that won't be helpful anywhere else). But at about half of the time it should have been made an outer class.
Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).
class Outer{
private int a;
class Inner{
private int b=0;
}
void outMethod(){
a = new Inner().b;
}
}
Because your main() method is in the ABC class, which can access its own inner class.

How can I create multiple interfaces of the same name in Java?

I am making a series of files to teach students interfaces, and each one will have an interface called Recycle in it. However, when I get to the second file, Eclipse gives me an error saying Recycle has already been defined. Here is roughly what my code looks like:
public class Example101
{
//methods here
}
interface Recycle
{
//abstract methods here
}
I'd really like to keep the interfaces in the same files as the example classes.
You can define types inside other types, using them as mini packages contained within one file:
public class Example101 {
interface Recycle {}
static class X implements Recycle {}
}
One thing you can't do is have the outer class Example101 itself implement an interface declared inside it. So to implement the interface you'll probably want another class declared inside Example101 too.
Member classes like X should be declared static, unless you want them bound to a created instance of the outer class Example101. To also declare the Recycle interface static is valid but redundant; member interfaces are always static (JLS §8.5.1). Alternatively, if you make the outer type Example101 an interface, all its member types are implicitly static (JLS §9.5).
Create packages.
Create the interfaces in the packages.

Using extends in Java gives enclosing instance error

I'm trying to use extends (inheritance) in Java. I made a quick abstract class to extend from, and then extended it. However my IDE now is saying that "An enclosing instance that contains abstract_class is required" and gives my constructor for the derived classes big error lines. What on earth is it going on about? The abstract class doesn't have or need any sort of constructor.
Just for reference, I'm using extends rather than implements in part because the implementation details that I don't want to have to maintain for every derived class which are identical involve using reflection on this.
Edit: I've read some of the responses. What in God's name is a static (or non-static, for that matter) class? And just to irritate all of you, it didn't solve the problem.
// some_class.java
public class some_class {
public static abstract class abstract_class {
...
}
...
}
// Model.java
public class Model extends some_class.abstract_class {
public Model(...) {
// No enclosing instance! Critical error.
...
}
...
}
And I thought that C++'s header files were bad.
The code you posted seems to compile just fine for me. Try doing a clean build in your IDE and it should work.
Just for your own curiosity, Java has 2 types of inner classes: static and regular or (non-static). If you don't include the static keyword for an inner class definition, it means that an instance of that class will always require an instance of the parent class. For ex:
public class MyClassOuter {
//...
public class MyClassInner {
//..
}
}
If you write that, it is understood that any instance of MyClassInner will have an implicit reference to an instance of MyClassOuter.
Static, on the other, hand implies no such thing. It is just a class definition that happens to be inside another class definition. The outer class is used almost like a package (though not quite).
if you have
interface MyInterface
{
abstract class MyAbstractClass {
// ...
}
}
and then you try
class ConcreteClass extends MyAbstractClass {
}
You will get the error described. The fix is to either move MyAbstractClass to a top-level class (put it in it's own file - not strictly necessary for non-public classes, but keeps the code organized.) Alternatively, add the static modifier to the MyAbstractClass declaration.
The "enclosing instance" message almost certainly implies that you have a (non-static) inner class for your superclass. In most cases, inner classes can and should be static - that's likely the best workaround here. Alternatively, as the message says, you will need to use an enclosing instance of the "outer" class, if your parent really makes sense as a non-static inner class.
Posting some code will help disambiguate between these causes and suggest the best way to resolve it. I'll also be able to give examples of the resolutions with the right class names - currently I don't think arbitrary names will help that much as it sounds like you hadn't identified the inner/outer class issue.
You need to in your child class add in the constructor super() that super class can be created.
class A{
.
.
.
class B{
. . .
}
}
if you want to access the Class B and it it is not static inner class you can write the code as
A.B objOfB = new A(). new B();

Why can outer Java classes access inner class private members?

I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:
class ABC{
class XYZ{
private int x=10;
}
public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}
Why is this behavior allowed?
The inner class is just a way to cleanly separate some functionality that really belongs to the original outer class. They are intended to be used when you have 2 requirements:
Some piece of functionality in your outer class would be most clear if it was implemented in a separate class.
Even though it's in a separate class, the functionality is very closely tied to way that the outer class works.
Given these requirements, inner classes have full access to their outer class. Since they're basically a member of the outer class, it makes sense that they have access to methods and attributes of the outer class -- including privates.
If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow:
class ABC{
private interface MyInterface{
void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.
The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.
There's a correct answer appearing on another question similar to this:
Why can the private member of an nested class be accessed by the methods of the enclosing class?
It says there's a definition of private scoping on JLS - Determining Accessibility:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Thilo added a good answer for your first question "How is this possible?". I wish to elaborate a bit on the second asked question: Why is this behavior allowed?
For starters, let's just be perfectly clear that this behavior is not limited to inner classes, which by definition are non-static nested types. This behavior is allowed for all nested types, including nested enums and interfaces which must be static and cannot have an enclosing instance. Basically, the model is a simplification down to the following statement: Nested code have full access to enclosing code - and vice versa.
So, why then? I think an example illustrate the point better.
Think of your body and your brain. If you inject heroin into your arm, your brain gets high. If the amygdala region of your brain see what he believe is a threat to your personally safety, say a wasp for example, he'll make your body turn the other way around and run for the hills without You "thinking" twice about it.
So, the brain is an intrinsic part of the body - and strangely enough, the other way around too. Using access control between such closely related entities forfeit their claim of relationship. If you do need access control, then you need to separate the classes more into truly distinct units. Until then, they are the same unit. A driving example for further studies would be to look at how a Java Iterator usually is implemented.
Unlimited access from enclosing code to nested code makes it, for the most part, rather useless to add access modifiers to fields and methods of a nested type. Doing so is adding clutter and might provide a false sense of safety for new comers of the Java programming language.
An IMHO important use case for inner classes is the factory pattern.
The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.
In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...
class MyPrivates {
static class Inner1 { private int test1 = 2; }
static class Inner2 { private int test2 = new Inner1().test1; }
public static void main(String[] args) {
System.out.println("Inner : "+new Inner2().test2);
}
}
Access restrictions are done on a per class basis. There is no way for a method declared in a class to not be able to access all of the instance/class members. It this stands to reason that inner classes also have unfettered access to the members of the outer class, and the outer class has unfettered access to the members of the inner class.
By putting a class inside another class you are making it tightly tied to the implementation, and anything that is part of the implementation should have access to the other parts.
The logic behind inner classes is that if you create an inner class in an outer class, that's because they will need to share a few things, and thus it makes sense for them to be able to have more flexibility than "regular" classes have.
If, in your case, it makes no sense for the classes to be able to see each other's inner workings - which basically means that the inner class could simply have been made a regular class, you can declare the inner class as static class XYZ. Using static will mean they will not share state (and, for example new ABC().new XYZ() won't work, and you will need to use new ABC.XYZ().
But, if that's the case, you should think about whether XYZ should really be an inner class and that maybe it deserves its own file. Sometimes it makes sense to create a static inner class (for example, if you need a small class that implements an interface your outer class is using, and that won't be helpful anywhere else). But at about half of the time it should have been made an outer class.
Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).
class Outer{
private int a;
class Inner{
private int b=0;
}
void outMethod(){
a = new Inner().b;
}
}
Because your main() method is in the ABC class, which can access its own inner class.

Categories

Resources