为什么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中声明类的方式,内部类有一个对外部类实例的隐式引用。因此出现错误消息:"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: Java中的内部类(非静态嵌套类)在c#中没有直接的语法转换,但我们可以编写显式等效的
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();
}
}
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();
}
}
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();
}
}
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
也不起作用。