Nesting Classes - java

If I nest a class inside another, does the nested class automatically become a subclass of the parent class? Would the nested class have access to all the public methods, vairables of the parent class?
Oh sorry - the programming language i am referring mainly to is Java!

If I nest a class inside another, does the nested class automatically become a subclass of the parent class?
No
Would the nested class have access to all the public methods, vairables of the parent class?
If the inner class is not static, yes. It also has access to any other members, static or not, and public or not. If the nested class is declared static then there is no enclosing instance, so it would only have access to the static members of the outer ("parent") class.

Nested class is not subclass of parent class. If nested class is not static , it can access all methods and variables of the parent class. If nested class is static, then it can access only static fields and methods.

What language is this in reference to? For most languages, an inner class and a subclass are completely different things. An inner class is a "member" of the outer class, just as fields and methods are members of the outer class. And just like any (static) method of the outer class can access all (static) class members, usually inner classes have access, as members of the outer class, to all other members of the outer class. (This is definitely not true of all OO languages, however.)

Related

All the classes in java belong to Object Class , then why can't a class be static

For a class being static, it is required it to be not a top level class. Since all classes belong to Object class which is the superior of all classes, then why can't we create a class with static keyword? Why is static classes allowed only in nested scenario.
All the classes in Java (transitively) extend Object, they are not inner classes inside it.
static wouldn't mean anything for top level classes, and therefore is forbidden. For inner classes, static means the same thing it means for other members (such as data members and methods) - the inner class belongs to the outer class, not to a specific instance of it.

Inner classes can access even the private members of the outer class.. doesn't it violates the privacy?

My interviewer asked me about inner classes.. After explaining him everything he stopped me on my one sentence- if inner classes can access private members of outer class then doesn't it violate privacy?
I was unable to answer it.
From a JVM perspective, yes, an inner class accessing a private member of the outer class violates privacy.
But, from a Java perspective, no, it does not violate privacy.
JVM perspective
The Java Virtual Machine Specification, section 5.4.4. Access Control says:
A field or method R is accessible to a class or interface D if and only if any of the following is true:
[...]
R is private and is declared in D.
So, the JVM will only allow private members to be accessed from code in the same class, i.e. a nested class cannot access private members of the outer class.
Java perspective
The Java Language Specification, section 6.6.1. Determining Accessibility says:
A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access:
[...]
Otherwise, the member or constructor is declared private, and 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.
So, a private member in a top-level class and/or nested class is accessible from code anywhere within that top-level class. Since nested classes by definition occur within the body of the enclosing top-level class, code in nested classes can access private members of the outer class.
Synthetic access
To solve the discrepancy, the Java compiler creates hidden (synthetic) methods for allowing "private" access between closely related classes, i.e. between a top-level class and all its nested classes.
This is an internal trick of the compiler and is not really documented in the specifications. JVMS, section 4.7.8. The Synthetic Attribute says:
[...] A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. [...]
The Synthetic attribute was introduced in JDK 1.1 to support nested classes and interfaces.
For more information, do a web search for java synthetic accessor.
See also: Synthetic accessor method warning
Answer is No as inner class is part of the outer class, just like other variable and methods are
All private variable/method of a class can be accessed inside all methods of the same class. An inner class is a special case where an instance of InnerClass can exist only within an instance of OuterClass. Hence it has direct access to the methods and fields of its enclosing instance.
The answer is NO, because inner class has internal link to the outer class and inner class does not exists without concrecte instance of outer class.
But if you add static to the inner class declaration, it means the it does not have link to the outer class and this is the same, when you declare class in it's own file.
That is all, clear and simple.
If you look closely at statement#1 and #2, you will find that the only difference between them is of one extra object (of inner class) that gets created in #1, rest everything access-wise is exactly same.
There is no violation because somewhere you're intentionally leaving the door open through some form of access specifier like public or protected. Inner class doesn't act (or is not capable to act) as a workaround in there, so no violation absolutely.
public class AccessPrivateMemberThruInnerClass {
private int getUniqueId() {
return 101;
}
private class AnInnerClass {
public int getParentID() {
return getUniqueId(); // invokes private method inside a public method.
}
}
public int getUniqueIdForce() {
return getUniqueId(); // invokes private method inside a public method.
}
public AnInnerClass getInnerClassObject(){
return new AnInnerClass();
}
public static void main(String[] args) {
AccessPrivateMemberThruInnerClass obj = new AccessPrivateMemberThruInnerClass();
System.out.println(obj.getInnerClassObject().getParentID()); // #1
System.out.println(obj.getUniqueIdForce()); // #2
}
}
Answer : No inner class does not voilate the privacy of outer class.
Explanation : All instance methods defined in a class are able to access the private or not private fields and methods defined in the class. This happens as all the instance methods and fields belong to the current object of the class.
Same is true for any inner (non static) class, it has an implicit reference of outerclass current object.
This is the reason as why you can only create the object of inner (non static) class with the help of an object of outer class. If you create the object of inner class inside any instance method of outer class then it is created with the help of implicit current object reference of the outer class.
If you have inner class which is static, then it does not has implicit reference to current object of outer class. Any instance field or method belong to an Object of the class. Hence static inner class can not access any private or non private instance field or method of outer class.
You can set reference of outer container class object explicitly and then it can acess. Now with the help of this explicitly set reference of outer class you can access the private Fields and methods.
So now lets modify the question as why inner static class with an explicit reference of outer class can acess and modify private methods and fields ?
Answer is related to our decision for having such design. The intention of defining any entity within the scope of a class is belongingness. If belongingness is missing then you should reconsider your decision lf making the class as inner (static or non static). Inner classes should be made when we wish to encapsulate a sub responsibility to an entity. This makes the related responsibility still cohesive.
Iterator is a part of any Collection and hence it is inner class. Custom AsyncTask class defined in custom Activity class in android is often made as private static (with weak reference of outer class activity) to prevwnt activity leak as the intention is to modify the fields which are private.
P.S : Afer compiler compiles the code it generates separate files for inner class and you can refer the link to understand as how the interaction of fields of one class being accessible to other class happens when other class is defined as inner class
https://stackoverflow.com/a/24312109/504133 . Actually synthetic getters and setters are injected in the code by compiler so as nested static class can access private fields using these. But still this is backend task done by langauge tools.

Static class Initialisation in Java

Is there a difference between initialisation of a static nested class and top level class?I understand that static class doesnt require an enclosing class instance but what happens if there are multiple instances of the static nested class? Just like static variables are shared by class instances, will the instances of the static class be shared also?
Let me see if I understand your question correctly.
A class can declare nested classes.
If a class C1 declares a non-static inner class C2, then C2 has access to all of C1's fields and methods, regardless of their access modifiers.
C2 is, in fact, treated as a field: its declaration is loaded whenever a new instance of C1 is created. This means that non-static inner classes are rather more expensive than static ones, and should be avoided if not strictly necessary.
If a class C1 declares a static inner class C3, then C3 is shared across all instances of C1. It has access to all static methods and fields of C1, but not to non static ones - C3 is by definition not tied to a specific instance of C1, so there is nothing for it to have access to.
When you declare a static inner class, you're not saying anything about its instances. You're just telling the compiler that the class' definition is shared across all instances of the enclosing class. So, no, instances of the nested static class aren't shared automatically.
A static nested class does not required an instance of the enclosing class (as you point out) so there is nothing to share.
If you have a static variable then every instance of the class will hold a reference to the same static variable. Changes in one class will change the variable in all classes.
As a class is immutable at run time then this same logic doesn't carry through.
An instance of a static nested class is effectively the same as an instance of any other class.
The only way an instance would be shared would be if you had a static variable pointing to an instance of a static nested class. In this case it is the same as any other static variable.
As is pointed out the the tutorial the only real different between a static nested class and a top level class is that a static nested class can access private static members of it's enclosing class.
Every class is a singleton object of type Class.
A static inner class is the base case. It is the other, normal inner class, that also has an OuterClass.this pointer for its instance objects.
So as such, there is no difference in class initialisation of any class.
The nested class as you declared it as "static class" does not differ from another top level class like inner class does. Adding the static to it declaration you promote it to be separated from owner class that became only a namespace for it.
package org.stack.question
public class Top {
public static class Nested {
}
}
To create a instance of Nested class you must only do this
Object instance = new org.stack.question.Top.Nested();
From specification:
Nested classes that are not inner classes may declare static members
freely, in accordance with the usual rules of the Java programming
language. Member interfaces (§8.5) are implicitly static so they are
never considered to be inner classes.

Java - Inner class constructor - allowed for outer class only

I have inner class in my code. I want to give public access to its instances, but only outer class should be able to create this instances, like in "private" access. Is it possible without making properly small package (or creating public interface for every such inner class)?
(Sorry if my english is bad :P)
It is possible. Declare your inner class public, but its constructor private. This way you can create it only inside your enclosing class and itself, but not from outside.
By default,If you want to get the instance of the inner class you need to have the Outer class first.
A inner class is a member of its enclosing class.
You need not to do anything for that.
Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private
I hope I understood your question in right way.
Please refer.
So make private of inner class.
public class Outer {
private class Inner {}
public String foo() {
return new Inner().toString();
}
}
you can't legally call the private default constructor because it is private

Can outer class be defined as static and enclose inner static class?

It correct to define an outer class as static which have inside also a static class? Only one instance of outer and inner classes is needed. Can outer class be abstract and it's enclosed class be static?
No, a top level class can't be static. The meaning of "static" in a class declaration is only relevant to nested classes. You can certainly have a static nested class within an abstract class though.
From the JLS section 8.1.1:
The modifier static pertains only to member classes (§8.5.1), not to top level or local or anonymous classes.
Note that if you want "only one instance" of a class, you should potentially make it a singleton - which is entirely separate, and not something which affects the class declaration itself.

Categories

Resources