簡體   English   中英

為什么java中的嵌套類與C#中的嵌套類在以下方面有所不同?

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

我找到了一些類似的帖子,但找不到能清楚地解釋這一點的答案。類,這是我遇到的場景

在 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: 錯誤:需要一個包含 external.inside 的封閉實例...

這是 Java 的情況.. 這個錯誤是什么?

這是否意味着外部類“outside”無法使用點運算符訪問內部類“inside”,因為它不是靜態的? 如果是這樣,那么為什么同樣不會在 c# 中生成編譯錯誤?

問題在於您在 Java 中聲明類的方式,內部類具有對外部類實例的隱式引用。 因此錯誤消息:“錯誤:需要一個包含outside.inside 的封閉實例”。 這意味着您需要:

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

通常,這種模式在 Java 中用於內部類的實例沒有外部類的實例而存在沒有意義的情況; 並注意內部類實例將可以訪問所有外部類實例的變量,甚至是私有變量。 但總的來說,這樣的類通常是private

為了使其消失,您必須使內部類static 然后你將能夠做到:

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

編輯:關於static在 Java 中的含義的完整說明:Java 中的static任何東西(變量、類、方法)都可以在類實例級別訪問。 例如,您可以從非靜態方法的實例中訪問靜態變量(這也意味着您可以從類的實例中調用靜態方法!); 但是靜態方法不能訪問非靜態變量,也不能調用“僅實例”方法等。

此外,“頂級”類不能是static ,因為它沒有意義。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM