样板例子如下:using System;
public abstract class A
{
public A()
{
Console.WriteLine('A');
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
} public class B: A
{
public B()
{
Console.WriteLine('B');
}
public new void Fun()
{
Console.WriteLine("B.Fun()");
}
public static void Main()
{
A a = new B();
a.Fun();
Console.ReadLine();
}
}这段程序的输出是A
B
A.Fun()Q1:不理解为什么a.Fun()输出的居然是 “A.Fun()”我的理论:
由 A a=new B() 这一句编译以后,a应该算是B的对象,为什么 a.Fun()输出的不是“B.Fun()”Q2:如果将B类中的 public new void Fun()
改为public override void Fun()
那么 a.Fun()输出的就是 “B.Fun()”了。请解释一下。
在这里,我理解的new就是用来隐藏父类的方法的。
override是用来重载的先写这么多,还有的疑问陆续登场
public abstract class A
{
public A()
{
Console.WriteLine('A');
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
} public class B: A
{
public B()
{
Console.WriteLine('B');
}
public new void Fun()
{
Console.WriteLine("B.Fun()");
}
public static void Main()
{
A a = new B();
a.Fun();
Console.ReadLine();
}
}这段程序的输出是A
B
A.Fun()Q1:不理解为什么a.Fun()输出的居然是 “A.Fun()”我的理论:
由 A a=new B() 这一句编译以后,a应该算是B的对象,为什么 a.Fun()输出的不是“B.Fun()”Q2:如果将B类中的 public new void Fun()
改为public override void Fun()
那么 a.Fun()输出的就是 “B.Fun()”了。请解释一下。
在这里,我理解的new就是用来隐藏父类的方法的。
override是用来重载的先写这么多,还有的疑问陆续登场
不过既然A为abstract class,那你至少应该把class A地Fun设成
public abstract void Fun(); //不提供任何实现
这样才显得abstract像个abstract
(对于2这种情况, 如果将B类中的 public new void Fun() 改为public override void Fun() 那么输出的的确是“B.Fun()”但是如果 B类中的Fun()方法 依然是 public new void Fun() 这样声明的话 输出的结果还是“A.Fun()”)
这个不是说抽象类像不像抽象类的问题啊题目就是这样的了。。
如果是的话,那么根据上面说的
2。如果A中的Fun()是virtual方法,那么在运行时,检查a引用的时哪个实例,然后确定属于哪个类,并调用相应的Fun(),那么就是说,如果A a=new B()这种情况下,a.Fun()输出的就应该是 “B.Fun()”
为什么输出的还是“A.Fun()”,而不是“B.Fun()”呢?
public abstract class A
{
public A()
{
Console.WriteLine('A');
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
} public class B: A
{
public B()
{
Console.WriteLine('B');
} ///////////////////////////////////////////
将new 改为override
public override void Fun()
{
Console.WriteLine("B.Fun()");
}
public static void Main()
{
A a = new B();
a.Fun();
Console.ReadLine();
}
}
如果要动态绑定,那就virtual + override.如果想A a = new B();时管它B里有同名方法,但照样想执行A.Fun(),那就new.关键是明白为什么要用new.
我要用它,那么我继承它。
public class B: A 继承后我不小心声明了一个和基类库中Fun()方法同名的一个Fun()方法。
A a = new B();
a.Fun();
这时,不加new,编译器就提出警告。它不知道你要执行哪个,你想动态捆绑,执行继承类的Fun(),你就加个override,编译器会告诉你。要么,加个new,为什么加new,你既然不是前一种情况,那你就明确告诉我Fun在B里是一种新的实现方法,它跟A里的Fun没关系。
也不知道我的理解对不对。
new关键字是覆盖基类型方法,并不属于“继承链”所以在lz程序中,继承链最末端就是基类的Fun(),
而B类改为override以后,继承链最末端变为B.Fun(),因此执行B.Fun()
这个说法好像比较正确的唉。。不过还有一个不明白的。。
A a=new B() 这样的话。。a应该算是B的对象的吧。B类本身也有Fun()函数,为什么不调用自己的呢?
{
Console.WriteLine("B.Fun()");
}
A a=new B() 这样的话。。a应该算是B的对象的吧。B类本身也有Fun()函数,为什么不调用自己的呢?
//===========================================================================类B有两个Fun函数,一个在VTable里,用于晚绑定,一个是普通的用于早绑定的函数
new关键字的意思就是忽略原来继承的那个函数,使用新定义的函数。
但是这里你是用a.Fun去调用,编译器认为是虚函数调用,所以调用的是B的VTable中的那个函数(就是从A继承来的),而在类型B上调用Fun,将不使用VTable,使用早绑定
(类A的VTable: Object::ToString()
Object::Equals()
Object::GetHashCode()
Object::GetType()
A::Fun()
类B的VTable : Object::ToString()
Object::Equals()
Object::GetHashCode()
Object::GetType()
A::Fun() //从A继承来
)
“override是用来重载的”首先这句话就有问题,你还没有理解什么是重载,什么是重写.
xs
为什么不会认为它是类B上的Fun()呢?恳求 回复人: Jim3(Jim) ( ) 信誉:105 大人帮忙说清楚一点。谢谢了。
MSDN 对virtual 和override的说明和示例
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/csref/html/vclrfVirtualPG.asp简单地说就是除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。 在静态属性上使用 virtual 修饰符是错误的。
通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性
我的理论:
由 A a=new B() 这一句编译以后,a应该算是B的对象,为什么 a.Fun()输出的不是“B.Fun()”
/*********************************************************************
你说a应该算是B的对象,这是不对的。a就是A类型的一个引用变量,a可以引用A类型的对象,也可以引用B类型的对象。在这里a.Fun()应该输出“A.Fun()”。为什么呢,因为B类里面的Fun()是用new修饰的,我想你的想法是:希望用父类的变量引用子类的对象,用以实现动态邦定。如果是这样,你用了new隐藏B的方法,a不会顺着下去找B的方法的。如果你用override修饰B的方法,a.Fun()就bind到B类的方法了。罗嗦说了这么多,不知道说清楚没有。
总之,一句话,你错在“这一句编译以后,a应该算是B的对象”,a绝对不是B的对象。a只不过可以通过as方法,去调用B有而A没有的方法。记住:a只是A类型的变量!
改为
public override void Fun()
那么 a.Fun()输出的就是 “B.Fun()”了。
请解释一下。
在这里,我理解的new就是用来隐藏父类的方法的。
override是用来重载的。
/*****************************************************8
你的理解是正确的!
上面我已经解释了,希望能对你有一点帮助!
为什么不会认为它是类B上的Fun()呢?
//===========================================================================假如你是编译器,你能从a.Fun()分析出要调用的是类B的Fun()么?至少目前的编译器没有这么做编译器的规则是:首先看你在那个类型上调用函数其次看你调用的函数是否虚函数,是就启用晚绑定,否就早绑定