C#多态 与 java多态到底相同么?

hanxu 2009-02-10 09:11:55
下面是csdn java板块的一个热帖:
写出以下代码的输出结果

class A{
public String f(D obj){return ("A and D");}
public String f(A obj){return ("A and A");}
}
class B extends A{
public String f(B obj){return ("B and B");}
public String f(A obj){return ("B and A");}
}
class C extends B{}
class D extends B{}

class test{
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.f(b)); A and A
System.out.println(a1.f(c)); A and A
System.out.println(a1.f(d)); A and D
System.out.println(a2.f(b)); B and A
System.out.println(a2.f(c)); B and A
System.out.println(a2.f(d)); A and D
System.out.println(b.f(b)); B and B
System.out.println(b.f(c)); B and B
System.out.println(b.f(d)); A and D
}

我把这个例子改写成了C#的 代码如下:
class test
{




static void Main(string[] args)
{
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
Console.WriteLine(a1.f(b)); // A and A
Console.WriteLine(a1.f(c)); // A and A
Console.WriteLine(a1.f(d)); // A and D
Console.WriteLine(a2.f(b)); // A and A
Console.WriteLine(a2.f(c)); // A and A
Console.WriteLine(a2.f(d)); // A and D
Console.WriteLine(b.f(b)); // B and B
Console.WriteLine(b.f(c)); // B and B
Console.WriteLine(b.f(d)); // B and B

}

}

class A
{
public String f(D obj) { return ("A and D"); }
public String f(A obj) { return ("A and A"); }
}
class B : A
{
public String f(B obj) { return ("B and B"); }
public String f(A obj) { return ("B and A"); }
}
class C : B { }
class D : B { }

屏幕输出语句后面的是输出结果,发现java和C#版的输入结果不完全相同,想知道原因?谢谢赐教
...全文
288 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
EveryCase 2009-02-11
  • 打赏
  • 举报
回复
猿敲月下码 2009-02-11
  • 打赏
  • 举报
回复
原理是一样的,有些细节方面不一样
zzxap 2009-02-11
  • 打赏
  • 举报
回复
一样的
rightyeah 2009-02-11
  • 打赏
  • 举报
回复
up\
Limpire 2009-02-11
  • 打赏
  • 举报
回复
这个好像改写有些问题:
Java的方法默认是虚方法(virtual),派生类覆盖(override)基类相同签名的方法。
C#要通过virtual/override来覆盖,如果没有这些关键字,派生类仅仅是隐藏了基类的方法,通过基类去调用,当然是执行基类的方法。
  • 打赏
  • 举报
回复
多态不是语言的,是OOP的处理问题的方式
所以c#与java多态只是表面不同,内涵一致
hsmserver 2009-02-11
  • 打赏
  • 举报
回复
面向对象的概念都是一样的
yinbanghui 2009-02-11
  • 打赏
  • 举报
回复
多态是面向对象的基本概念,应该对c#和java都一样
龙宜坡 2009-02-11
  • 打赏
  • 举报
回复
以下引用自:http://www.cnblogs.com/sharmy/archive/2008/05/20/1203433.html


首先理解一下什么叫多态。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。

多态性通过派生类覆写基类中的虚函数型方法来实现。



多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。

编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。

运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过覆写虚成员实现。



下面我们来分别说明一下多态中涉及到的四个概念:重载,覆写,虚方法和抽象方法。

重载和覆写的区别:

重载

类中定义的方法的不同版本

public int Calculate(int x, int y)

public double Calculate(double x, double y)

特点(两必须一可以)

方法名必须相同

参数列表必须不相同

返回值类型可以不相同

覆写

子类中为满足自己的需要来重复定义某个方法的不同实现。

通过使用override关键字来实现覆写。

只有虚方法和抽象方法才能被覆写。

要求(三相同)

相同的方法名称

相同的参数列表

相同的返回值类型

最后再来介绍一下虚方法和抽象方法

虚方法:

声明使用virtual关键字。

调用虚方法,运行时将确定调用对象是什么类的实例,并调用适当的覆写的方法。

虚方法可以有实现体。


抽象方法:

必须被派生类覆写的方法。

可以看成是没有实现体的虚方法。

如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法。


注意:

昨天突然发现c#,和c++俩种语言在多态性的 实现机制 上面的细微差别。

如果是C++,在基类的构造函数里面调用虚函数的话,会调用本类的不会调用派生类的,原因是基类构造的时候,虚表还没有被派生类继承和修改。

但如果是C#,那就不同了,在基类的构造函数里面照样调用派生类的。不知道有谁知道c#它的这种底层机制是怎样的?
-------是这样的,C++会先初始化基类,然后逐级初始化派生类型。C#则是一开始就把对象创建好了,然后逐个调用构造函数。本质区别在于C++的构造函数的任务是初始化,C#则不然,C#的类型的任何字段不必初始化,均有默认值,所以C#在调用构造函数之前就已经将对象初始化完毕了。

通过继承,一个类可以用作多种类型:可以用作它自己的类型、任何基类型,或者在实现接口时用作任何接口类型。这称为多态性。C#中的每种类型都是多态的。类型可用作它们自己的类型或用作Object实例,因为任何类型都自动将Object当作基类型。

多态性不仅对派生类很重要,对基类也很重要。任何情况下,使用基类实际上都可能是在使用已强制转换为基类类型的派生类对象。基类的设计者可以预测到其基类中可能会在派生类中发生更改的方面。例如,表示汽车的基类可能包含这样的行为:当考虑的汽车为小型货车或敞篷汽车时,这些行为将会改变。基类可以将这些类成员标记为虚拟的,从而允许表示敞篷汽车和小型货车的派生类重写该行为。
hanxu 2009-02-11
  • 打赏
  • 举报
回复
自己顶

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧