namespace TestInterview
{
public class A
{
public void printA()
{
Console.WriteLine("printA");
}
public virtual void valueA()
{
Console.WriteLine("valueA");
}
}
public class B:A
{
public new void printA() //隐藏
{
Console.WriteLine("printB");
}
public override void valueA() //覆盖
{
Console.WriteLine("valueB");
}
}
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
//
B BTemp= new B();
A ATemp= new A();
ATemp = BTemp ;
ATemp.printA();
ATemp.valueA();
BTemp.printA();
BTemp.valueA();
Console.ReadLine();
}
}
}
------------------------------------------
结果:printA
valueB
printB
valueB
为什么?为什么不是:printB
valueB
printB
valueB
对于第一种情况
A ATemp = new B();
ATemp.printA();
由于printA()并不是一个虚方法,而且在B中是这样定义的new public void printA(){},这个new的意思是说这个方法是专属于类B的,和类A一点关系都没有
ATemp.printA();也绝对不等价于BTemp.printA(); ATemp只是一个对象的引用,并不是真正的一个对象,由于派生类的对象总是可以看做是一个基类对象,所以A ATemp = new B(); 这句话是成立的,但并不代表ATemp就是B类的对象!
对于第二种情况
ATemp.valueA();只所以出来的结果是ValueB,那是因为B中是这样定义的public override void valueA(){},override代表子类覆盖了父类的方法,但ATemp仍是个指向基类的对象的引用,当有和父类同名且参数列表相同的方法时,会调用子类的方法,这也正是面向对象编程多态的特征,但不代表ATemp是B类的对象,不然你在B类随便试试加一个方法,看看ATemp是否能调用
ATemp = BTemp ;赋值后ATemp 指向BTemp 他内在数据还是BTemp类型的.具有多态.但因为printA方法使用了new操作符则这两个方法没什么关系,该方法不具有多态.显式调用Atemp还是会调用Atemp类的printA方法.