[英]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.