看到辣妹子《天啊!》一文后,动手调试才发现是个Java程序,我把它改为了.net程序,才看出来为什么“天啊!”了。实际上从一个侧面可以看出Java与.NET的相同与相异的地方。在这里放上修改后的.net程序:
using System;
class Outer
{
private static string foo = "Outer.foo";
private static string bar = "Outer.bar";
private Inner1 inner1 = new Inner1();
private Inner2 inner2 = new Inner2();
private class Inner1
{
private string bar = "Inner1.bar";
public Inner1()
{
Console.WriteLine("new " + this.ToString() + ": ");
Console.WriteLine(" foo=" + getFoo());
Console.WriteLine(" bar=" + getBar());
}
string getFoo()
{
return foo;
}
string getBar()
{
return bar;
}
}
private class Inner2 : Inner1
{
private string foo = "Inner2.foo";
public Inner2()
{
}
string getFoo()
{
return foo;
}
string getBar()
{
return bar;
}
}
public static void Main(String[] args)
{
new Outer();
}
}
class Outer
{
private static string foo = "Outer.foo";
private static string bar = "Outer.bar";
private Inner1 inner1 = new Inner1();
private Inner2 inner2 = new Inner2();
private class Inner1
{
private string bar = "Inner1.bar";
public Inner1()
{
Console.WriteLine("new " + this.ToString() + ": ");
Console.WriteLine(" foo=" + getFoo());
Console.WriteLine(" bar=" + getBar());
}
string getFoo()
{
return foo;
}
string getBar()
{
return bar;
}
}
private class Inner2 : Inner1
{
private string foo = "Inner2.foo";
public Inner2()
{
}
string getFoo()
{
return foo;
}
string getBar()
{
return bar;
}
}
public static void Main(String[] args)
{
new Outer();
}
}
问题的关键在于以下几点:
1、Outer类中的字段foo和bar在.net环境下必须为静态成员。否则在嵌套类Inner1与Inner2中无法访问这些字段。
2、子类在构造时会先调用父类的构造函数完成父类构造后再调用自己的构造函数完成子类构造。
3、父类有的字段在子类都有,只不过受到访问权限的限制而已。关于这点,可以参考我的另外一篇文章《从编译角度看对象访问控制》。这可以通过在Inner2的构造函数中添加以下两条命令检测一下。
Console.WriteLine(" foo=" + getFoo());
Console.WriteLine(" bar=" + getBar());
Console.WriteLine(" bar=" + getBar());
关于程序的执行顺序可以在.net下单步跟踪实现。