class A
{
public void F()
{
Console.WriteLine("A.F");
}
public virtual void G()
{
Console.WriteLine("A.G");
}
}class B : A
{
new public void F()
{
Console.WriteLine("B.F");
}
public override void G()
{
Console.WriteLine("B.G");
}
}class Test
{
static void Main()
{
B b = new B();
A a = b;
a.F();
b.F();
a.G();
b.G();
}
} A a = b; 这个a到底是A类的还是B类的啊,为什么 a.F();a.G(); 显示的是B.F B.G呢 谢谢
{
public void F()
{
Console.WriteLine("A.F");
}
public virtual void G()
{
Console.WriteLine("A.G");
}
}class B : A
{
new public void F()
{
Console.WriteLine("B.F");
}
public override void G()
{
Console.WriteLine("B.G");
}
}class Test
{
static void Main()
{
B b = new B();
A a = b;
a.F();
b.F();
a.G();
b.G();
}
} A a = b; 这个a到底是A类的还是B类的啊,为什么 a.F();a.G(); 显示的是B.F B.G呢 谢谢
前面不是用A定义的吗?你觉得呢?他只是用A的子类B来实例化
第二个问题,自己到MSDN去好看看类继承之间的关系
这里只是声明变量a是A类,于是编译器在编译随后的代码时就允许a变量可以引用任何兼容于a类的对象,例如B的子类也是兼容于A类。
楼主,我来给你分析一下代码: A a = b; 这个a到底是A类的还是B类的啊? LZ, 里面的 a 是A的 声明 类。 懂? 因为B类是继承A类的,代码很明显, 它首先 B b = new B();这样,B声明了一个b的声明类,而实现类也是B本身(NEW B()), 所以下面代码 A a = b;其实也就是B是实现类,所以打印a.F的时候,调用的B本身,也就是这个方法啦: new public void F()
{
Console.WriteLine("B.F");
}所以打印出来的是方法里的B.F
我们再来分析一下a.G 打印出来的为什么是B.G?
看代码: 因为小 a 是 A的声明类,所以,而且调用的是a.G这个方法,并没有接实现类,所以这个方法调用自己本身。但。LZ,请仔细看,A类里面的这个方法: public virtual void G()
{
Console.WriteLine("A.G");
很明显它是虚方法。定义了关键字Vritural, 因为B类是继承A类的,我们还要再来看B类的G()方法: public override void G()
{
Console.WriteLine("B.G");
很明显的,对A类的G方法进行了重写,它用了overiride关键字对A类 G 的方法进行重写了。SO。。打印出来的结果很自然的就是 B.F 和 B.G 了,LZ,懂吗? 不懂,欢迎继续追问。
显然,A.F()将执行A类中的F()
a.F()将显示A.F
a.F() 会找它实际 new 的对象的 F() 方法,但是发现 B 类的 F() 方法被 new 了,所以他往上按照继承线搜索,找到第一个没有被 new 过的继承下来的方法。
a.G() 没什么,G() 被重写,而且 a 变量指向的又是 B 类的对象,所以就调用 B 类的方法 G()。
A a = b;
主要是这两句话,看第二句,把b方法付给了a 所以后面引用到的都是在a里的
B.F
B.G
B.G
在多态对象中,调用隐藏方法时,调用的是父类的方法;
调用覆盖方法时,调用的是子类的方法;
LZ,不好意思,看错了。我勒个去。a.F() 这个方法 打印出来的应该是 A.F才对,因为:A a = b;
a.F();思路还是没错的,a 是 A 的声明类,b是实现类。 b并没有 实例化 对象。 在来看看 A 类的 F 的方法,子类并没有进行重写。所以调用 的应该是 A 类 自身的 F 方法才对。所以打印出来的是 A.F 才对。靠一失足 成千古恨啊。 LZ,不懂的欢迎继续 追问。最后 打印 出来的 四个 结果是: A.F B.F B.G B.G。
//《1》
int i = 10;
object obj = i;//你说obj 不就是10吗。
//《2》
object obja = new A();//obja 又是什么?
//《3》
object o;
A a = new A();//[A]
B b = a;
o = b;//你说为是什么? 不就是 (//[A])在这里创建得吗。
new public void F()
{
Console.WriteLine("B.F");
}这个new表示什么?
我是初学者.
我知道是的,B 类中 这个new 的这个函数 表示 对基类 A 的同名函数复盖。
没错,楼上解析的不错。 虽然是New了,但并没有对这个 方法 进行 重写。
还有个问题就是我看了个帖子说的是,
序号 基类(A)中是否有virtual 子类(B)中是否有override 输出(B输出)
1 是 是 B.G
2 是 否 B.G
3 否 是 编译错误
4 否 否 B.G请问下这样总结对不对啊 谢谢大家的热心帮助。
你可以记住这么多规则,然后去使用,比如多态。
如果你要追根问底,就要去看看CLR是怎么调用实例方法,虚方法(抽像方法本质上也是虚方法),静态方法的。当你理解了这些工作机制,这些问题就迎刃而解了。
楼主,你首先得理清概念先。看看父类是不是虚方法或者抽象方法(Vritural或Abstract)。 子类有没对父类的方法进行重写(Override),重写了,就对父类的方法就有影响了。
a.F();调用的谁,这就看就掌握一个就近原则。
A a只是声明 了一个A类型的指针,其实实体是b.
搞清楚b是个什么类型的东东就OK了嘛。
基类不用 public void F(),子类也用public void F() 结果显示的也是子类的值, 这样感觉Override 没什么意义了啊,求解 谢谢大家
class A
{
public void F()
{
Console.WriteLine("A.F");
}
public virtual void G()
{
Console.WriteLine("A.G");
}
}class B : A
{
new public void F()
{
Console.WriteLine("B.F");
}
public override void G()
{
Console.WriteLine("B.G");
}
}class Test
{
static void Main()
{
B b = new B();
A a = b;
a.F();
b.F();
a.G();
b.G();
}
}昨天刚看了有关C#继承及多态的东西;对于LZ的问题我的理解如下:
首先B b = new B();
A a = b;
这两行代码:声明了一个A类型对象的引用即a,一个B类型对象的引用即b;
由于A,B之间存在继承关系,这样a,b之间存在赋值兼容性,故可以将一个B类型的变量(b)赋值给A类型的变量的引用。
也即是说:a,b两个应用指向同一个对象(new B()这个对象).注意了这里值相同一个对象是有差别的:对于引用a,只有对象中的基类成分对它是可见的;而对于b,整个对象的所有成分对它都是可见的。这就解释了a.F();的执行结果为"A.F",B累中的F()方法对a不可见。
下一个疑点:为什么a.G()执行的是B类中的G()方法呢?
这就得理解一下virtual、override这两个关键字了:override的作用就是使基类的引用(即a)可以访问派生类中的同名成员(具体而言是相同的签名),而这个成员必须使用override关键字标注,同时基类中的同名成员使用virtual关键字来标注。可以这样理解:执行A.G() 时,本该调用A类中的G()方法,但A类中的G()方法前有virtual关键字,调用即转移到B类中的带override关键字的同名方法,所以最后执行的是B类中的G()方法,结果输出的自然是"B.G".
不知道楼主看懂了我上面说的后,现在有没有搞懂;
其实楼上也有的说到了B类中的F()方法加new关键字只是为了避免编译器的警告,LZ可以去掉那个new,执行结果将是相同的。
说这么多,我觉得LZ最重要的是要理解new,virtual,override这几个关键字的用处
a.F();a.G() 显示的是A.F B.G,而不是B.F B.G
原因:
1、a.F()是非虚方法,是被b.F() new的,所以调用a.F()的时候不会执行b.F();
2、a.G()是虚方法,是被b.G()override的,所以调用a.G()的时候,会执行b.G().
这就是new和override的区别,也是多态的精髓。
a.F();a.G() 显示的是A.F B.G,而不是B.F B.G
原因:
1、a.F()是非虚方法,是被b.F() new的,所以调用a.F()的时候不会执行b.F();
2、a.G()是虚方法,是被b.G()override的,所以调用a.G()的时候,会执行b.G().
这就是new和override的区别,也是多态的精髓。
而且这个执行的应该是A的方法
在主函数中新建若干个student类的对象(四个以上),分别以学号,姓名,年龄,各科成绩作为参数。并分别调用上述的两个方法。
急求帮助。明天考试要用。