I found a couple of posts resembling this, but couldn't find an answer that trenchantly explains this..
I have performed nesting of a class, i.e class 'inside' is present in class 'outside' and made an attempt to instantiate the inner class, and this is the scenario that i came across through
In case of C# :
class outside
{
public class inside
{
public void print()
{
System.Console.WriteLine("I am inside");
}
}
}
class Program
{
public static void Main(string[] args)
{
/* here i am trying to instantiate the inner class 'inside' */
outside.inside obj = new outside.inside();
obj.print();
Console.ReadKey();
}
}
Output:
I am inside
So, the above is working fine..But,
In case of Java :
class outside
{
public class inside
{
public void print()
{
System.out.println("I am inside");
}
}
}
class Demo
{
public static void main(String[] args)
{
/* here i am trying to instantiate the class 'inside' */
outside.inside obj=new outside.inside();
obj.print();
}
}
Output:
Demo.java:16: error: an enclosing instance that contains
outside.inside is required...
This is the situation in case of Java.. What this error is ?
Does it mean that the outer class 'outside' cannot access inner class 'inside' using the dot operator because it is not static? If so, then why the same doesn't generate a compilation error in c# ?
The problem is that the way you have declared classes in Java, the inner class has an implicit reference to an instance of the outer class. Hence the error message: "error: an enclosing instance that contains outside.inside is required". This means you need to:
Outside out = new Outside();
Outside.Inside in = out.new Inside();
In general, this pattern is used in Java in situations where it makes no sense for an instance of the inner class to exist without an instance of the outer class; and note that the inner class instance will have access to all of the outer class instance's variables, even private ones. But in general, such classes are generally private
.
In order for this to disappear, you must make the inner class static
. And then you will be able to do:
Outside.Inside in = new Outside.Inside();
Edit: completent on what static
means in Java: static
whatevers (variables, classes, methods) in Java are accessible at the class and instance level. You can access a static variable from a non static method for instance (this also means you can call static methods from an instance of a class!); but a static method CANNOT access a non static variable, nor invoke an "instance only" method etc.
Also, a "top level" class cannot be static
, because it makes no sense.
The syntax for nested classes in Java is slightly different from C#. Here is a better comparison of the two. By looking at the C# translations of the following two passages of Java code, you can get a better idea for what Java's doing behind the scenes. For an additional reference, see this link.
A static nested class in Java works like a nested class in C#.
Java:
class Outside {
public static class Inside {
public void print() {
System.out.println("I am inside");
}
}
}
class Demo {
public static void main(String[] args) {
Outside.Inside obj = new Outside.Inside();
obj.print();
}
}
C#:
class Outside
{
public class Inside
{
public void Print()
{
System.Console.WriteLine("I am inside");
}
}
}
class Program
{
public static void Main(string[] args)
{
Outside.Inside obj = new Outside.Inside();
obj.Print();
}
}
An inner class (non-static nested class) in Java does not have a direct syntax translation in C#, but we can write the explicit equivalent.
Java:
class Outside {
public class Inside {
public void print() {
System.out.println("I am inside");
}
}
}
class Demo {
public static void main(String[] args) {
Outside out = new Outside();
Outside.Inside obj = out.new Inside();
obj.print();
}
}
C#:
class Outside
{
public class Inside
{
private Outside _outer;
public Inside(Outside outer)
{
if (outer == null)
throw new ArgumentNullException("outer");
_outer = outer;
}
public void Print()
{
System.Console.WriteLine("I am inside");
}
}
}
class Program
{
public static void Main(string[] args)
{
Outside outside = new Outside();
Outside.Inside obj = new Outside.Inside(outside);
obj.Print();
}
}
In java,
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Why is this different in C#?
Because it's another language.