4

我发现了一些类似的帖子,但找不到明确解释这一点的答案。我已经执行了一个类的嵌套,即“内部”类存在于“外部”类中,并尝试实例化内部上课,这是我遇到的场景

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

输出:

我在里面 所以,上面的工作正常..但是,
如果是 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();
    }
} 

输出:

Demo.java:16:错误:需要包含 outside.inside 的封闭实例...

这是Java的情况。这个错误是什么?

这是否意味着外部类“外部”不能使用点运算符访问内部类“内部”,因为它不是静态的?如果是这样,那么为什么同样不会在 c# 中产生编译错误?

4

4 回答 4

10

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.

于 2013-06-07T14:33:45.197 回答
2

Java 中嵌套类的语法与 C# 略有不同。这是两者的更好比较。通过查看以下两段 Java 代码的 C# 翻译,您可以更好地了解 Java 在幕后所做的事情。有关其他参考,请参阅此链接

Java 中的静态嵌套类的工作方式类似于 C# 中的嵌套类。

爪哇:

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

Java 中的内部类(非静态嵌套类)在 C# 中没有直接的语法翻译,但我们可以编写显式等价物。

爪哇:

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();
    }
}
于 2013-06-07T14:52:14.257 回答
1

在java中,

要实例化内部类,您必须先实例化外部类。然后,使用以下语法在外部对象中创建内部对象:

OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

为什么这在 C# 中有所不同?因为它是另一种语言。

于 2013-06-07T14:35:48.813 回答
0

在 C# 中,嵌套类(包括其静态和非静态方法)可以访问外部类类型的对象的所有静态和非静态成员和方法,包括外部类本身,而不管保护级别如何。保护级别仅在从嵌套外部或外部类外部访问时才重要。

无论保护级别如何,都不能在嵌套类类型的对象上访问外部类的非静态成员和方法(即使在外部类或嵌套类中访问它也是不可能的,或者完全是另一个类);您必须使用外部类对象。同样,不能通过嵌套类名访问外部类的静态成员和方法,必须使用外部类名。

外部类不能访问嵌套类的私有成员(静态或非静态)(通过嵌套类类型的对象或通过嵌套类本身),但它可以实例化该类,因为嵌套的类类型外部类始终可以访问类本身。这意味着如果嵌套类是私有的,但静态成员不是私有的,那么它将能够访问该成员,但如果该成员是私有的,那么它将无法访问该成员。在这种情况下,从外部类访问就像完全从程序集中的另一个类访问一样。

无论保护级别如何,您都不能在外部类类型的对象上访问嵌套类的非静态成员和方法;您必须使用内部类对象。同样,不能通过外部类名访问嵌套类的静态成员和方法,必须使用内部类名。

在 C# 中,外部和嵌套类对象总是作为单独的对象实例化,但您可以将外部类的引用放在嵌套类中,并将嵌套类的引用放在外部类中。

在 Java 中,如果嵌套类不是静态的,则称为内部类。内部类和外部类是分别实例化的,但是您需要使用外部对象来实例化内部对象,这意味着内部对象始终与外部对象相关联。这意味着您需要先实例化一个外部对象。然而,内部对象不是外部对象的成员,外部对象也不是内部对象的成员,因此您必须明确地将其设为一个才能访问与类外部配对的对象. 但是,在内部类内部,您可以outerclass.this.method使用特殊版本的this- 根据需要访问所有外部对象成员和方法this要做到这一点,你不能在内部类之外访问它。在外部类内部,您不能访问绑定到外部对象的内部对象,innerclass.this.method2因为特殊this用途仅用于获取对象的外部对象this。这是因为一个外部对象可以有许多内部对象,所以它会模棱两可并且是不允许的。

Java 和 C# 之间的另一个区别是,您可以通过 Java 中内部类类型的对象(如第 3 段所述)从外部类中访问私有内部成员。

Java 和 C# 之间的另一个区别是,Java 中的静态嵌套类与 C++ 和 C# 等其他语言的静态嵌套类不同,Java 中没有对应的静态嵌套类。Java 中的静态嵌套类是 C# 中的常规嵌套类——它只是取消了嵌套类需要使用外部类的对象来实例化的要求,而是可以分别实例化外部和嵌套类的对象,并且因此特殊的this也不起作用。

于 2021-04-07T21:53:36.610 回答