Why do nested classes in java differ from nested c

2019-05-05 13:41发布

问题:

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# ?

回答1:

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.



回答2:

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();
    }
}


回答3:

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.



标签: c# java oop