简体   繁体   English

为什么java中的嵌套类与C#中的嵌套类在以下方面有所不同?

[英]Why do nested classes in java differ from nested classes in C# in the following aspect?

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, ie 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# :在 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 :在 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... Demo.java:16: 错误:需要一个包含 external.inside 的封闭实例...

This is the situation in case of Java.. What this error is ?这是 Java 的情况.. 这个错误是什么?

Does it mean that the outer class 'outside' cannot access inner class 'inside' using the dot operator because it is not static?这是否意味着外部类“outside”无法使用点运算符访问内部类“inside”,因为它不是静态的? If so, then why the same doesn't generate a compilation error in c# ?如果是这样,那么为什么同样不会在 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.问题在于您在 Java 中声明类的方式,内部类具有对外部类实例的隐式引用。 Hence the error message: "error: an enclosing instance that contains outside.inside is required".因此错误消息:“错误:需要一个包含outside.inside 的封闭实例”。 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;通常,这种模式在 Java 中用于内部类的实例没有外部类的实例而存在没有意义的情况; 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 .但总的来说,这样的类通常是private

In order for this to disappear, you must make the inner class static .为了使其消失,您必须使内部类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.编辑:关于static在 Java 中的含义的完整说明:Java 中的static任何东西(变量、类、方法)都可以在类实例级别访问。 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.此外,“顶级”类不能是static ,因为它没有意义。

The syntax for nested classes in Java is slightly different from C#. Java 中嵌套类的语法与 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.通过查看以下两段 Java 代码的 C# 翻译,您可以更好地了解 Java 在幕后做了什么。 For an additional reference, see this link .如需其他参考, 请参阅此链接

A static nested class in Java works like a nested class in C#. Java 中的静态嵌套类的工作方式类似于 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#: 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 中的内部类(非静态嵌套类)在 C# 中没有直接的语法转换,但我们可以编写显式等效项。

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#: 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,在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#?为什么这在 C# 中有所不同? Because it's another language.因为它是另一种语言。

In C#, a nested class (including its static and non static methods) can access all static and non-static members and methods of an object of the type of the outer class, including the outer class itself, regardless of the protection level.在 C# 中,嵌套类(包括其静态和非静态方法)可以访问外部类类型的对象的所有静态和非静态成员和方法,包括外部类本身,无论保护级别如何。 The protection level only matters when accessing it from outside of the nested or outside of the outer class.保护级别仅在从嵌套类外部或外部类外部访问时才重要。

You cannot access the non-static members and methods of the outer class on an object of the type of the nested class, regardless of the protection level (it is not possible even if it is being accessed in the outer class or the nested class or another class entirely);不能在嵌套类类型的对象上访问外部类的非静态成员和方法,无论保护级别如何(即使在外部类或嵌套类中访问也不可能)完全另一个类); you have to use an outer class object.您必须使用外部类对象。 Similarly, you cannot access the static members and methods of the outer class via the nested class name, you have to use the outer class name.同样,不能通过嵌套类名访问外部类的静态成员和方法,必须使用外部类名。

An outer class cannot access private members (static or non-static) of the nested class (via an object of the type of the nested class or via the nested class itself), but it can instantiate the class because the class type of the nested class itself is always accessible to the outer class.外部类不能访问嵌套类的私有成员(静态或非静态)(通过嵌套类类型的对象或通过嵌套类本身),但它可以实例化类,因为嵌套类的类类型外部类始终可以访问类本身。 This means if the nested class is private but a static member is not private then it will be able to access the member, but if the member is private then it won't be able to access the member.这意味着如果嵌套类是私有的但静态成员不是私有的,那么它将能够访问该成员,但如果该成员是私有的,则它将无法访问该成员。 In this instance accessing from the outer class is like accessing from another class in the assembly entirely.在这种情况下,从外部类访问就像完全从程序集中的另一个类访问一样。

You cannot access the non-static members and methods of the nested class on an object of the type of the outer class, regardless of the protection level;无论保护级别如何,都不能在外部类类型的对象上访问嵌套类的非静态成员和方法; you have to use an inner class object.你必须使用内部类对象。 Similarly, you cannot access the static members and methods of the nested class via the outer class name, you have to use the inner class name.同样,不能通过外部类名访问嵌套类的静态成员和方法,必须使用内部类名。

In C#, the outer and nested class objects are always instantiated as separate objects, but you can place a reference to the outer class in the nested class and a reference to the nested class in the outer class.在 C# 中,外部和嵌套类对象总是被实例化为单独的对象,但您可以在嵌套类中放置对外部类的引用,在外部类中放置对嵌套类的引用。

In Java, the nested class is called an inner class if it is not static.在 Java 中,如果嵌套类不是静态的,则称为内部类。 An inner and outer class are instantiated separately but you need to use the outer object in order to instantiate the inner object, meaning that the inner object is always associated with an outer object.内部和外部类分别实例化,但您需要使用外部对象来实例化内部对象,这意味着内部对象始终与外部对象相关联。 This means that you need to instantiate an outer object first.这意味着您需要先实例化一个外部对象。 The inner object is however not a member of the outer object and the outer object is not a member of the inner object, so you have to explicitly make it one in order to be able access the object that it is paired with outside of the class.然而,内部对象不是外部对象的成员,外部对象也不是内部对象的成员,因此您必须明确地将其设为一个,以便能够访问与类外部配对的对象. Inside the inner class however, you can access all outer object members and methods using outerclass.this.method using the special version of this – as you need this to do it, you can't access it outside of the inner class.然而,内部类里面,你可以使用访问所有外部对象成员和方法outerclass.this.method使用的特殊版本, this -因为你需要this做,你不能外部访问内部类的吧。 Inside the outer class, you cannot access the inner object tied to an outer object using innerclass.this.method2 as the special this is used to get the outer object of the this object only.在外部类内部,您不能使用innerclass.this.method2访问绑定到外部对象的内部对象,因为特殊的this仅用于获取this对象的外部对象。 This is because an outer object can have many inner objects, so it would be ambiguous and is disallowed.这是因为一个外部对象可以有许多内部对象,所以它是不明确的,是不允许的。

Another difference between Java and C# is the fact that you can access private inner members from within the outer class via an object of the type of the inner class (as paragraph 3 mentioned) in Java. Java 和 C# 之间的另一个区别是,您可以通过 Java 中内部类类型的对象(如第 3 段所述)从外部类内部访问私有内部成员。

Another difference between Java and C# is that a static nested class in Java is different to the static nested classes of other languages like C++ and C#, for which there is no equivalent in Java. Java 和 C# 之间的另一个区别是 Java 中的静态嵌套类与其他语言(如 C++ 和 C#)的静态嵌套类不同,Java 中没有对等物。 A static nested class in Java is a regular nested class in C# – It just removes the requirement that the nested class needs to be instantiated using an object of the outer class, instead an object of the outer and nested class can be instantiated separately, and hence the special this does not work either. Java中的静态嵌套类是C#中的常规嵌套类——它只是取消了嵌套类需要使用外部类的对象实例化的要求,而是可以分别实例化外部类和嵌套类的对象,并且因此特殊的this也不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM