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

本文关键字:嵌套 方面 有所不同 java 为什么 | 更新日期: 2023-09-27 18:17:28

我找到了几个类似的帖子,但找不到一个能深刻解释这一点的答案。我已经执行了类的嵌套,即类"内部"存在于类"外部"中,并尝试实例化内部类,这是我通过

遇到的场景

对于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: error:一个包含在外面。Inside is required…

这是Java的情况。

是否意味着外部类'outside'不能访问内部类'inside'使用点操作符,因为它不是静态的?

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

问题在于你在Java中声明类的方式,内部类有一个对外部类实例的隐式引用。因此出现错误消息:"error:一个包含outside的封闭实例。Inside是必需的。"这意味着您需要:

Outside out = new Outside();
Outside.Inside in = out.new Inside();

一般来说,在Java中,当内部类的实例没有外部类的实例而存在是没有意义的情况下,使用这种模式;请注意,内部类实例可以访问所有外部类实例的变量,甚至是私有变量。但一般来说,这样的类一般是private

为了使其消失,您必须使内部类static。然后你就可以这样做:

Outside.Inside in = new Outside.Inside();

编辑:完全关于static在Java中的含义:static无论什么(变量,类,方法)在Java中都可以在类实例级别访问。你可以从实例的非静态方法访问静态变量(这也意味着你可以从类的实例调用静态方法!);但是静态方法不能访问非静态变量,也不能调用"仅限实例"的方法等。

同样,"顶级"类不能是static,因为它没有意义。

Java中嵌套类的语法与c#略有不同。这里有一个更好的比较。通过查看下面两段Java代码的c#翻译,您可以更好地了解Java在幕后所做的工作。如需更多参考资料,请参阅此链接。

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

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#中没有直接的语法转换,但我们可以编写显式等效的

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

java中

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

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

为什么这在c#中不同?因为这是另一种语言

在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也不起作用。