我正在玩多态概念。我认为所有的OOP概念在每种语言中都是相同的(差不多)。我编译并运行了这段代码,但java和c#给出了不同的答案:
public class Employee
{
// constructor implemented
public void mailCheck()
{
Console.WriteLine("In Employee Method\n Mailing a check to "+ this.name+ " " + this.address);
}
}
public class Salary : Employee
{
//constructor implemented
public void mailCheck()
{
Console.WriteLine("Within mailCheck of Salary class ");
Console.WriteLine("Mailing check to " + getName() + " with salary " + salary);
}
}
class driver
{
static void Main(string[] args)
{
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
e.mailCheck();
}
}
如果我在java中运行此代码,则调用salary class方法,如果我在c#中运行此代码,则调用employee类方法。
为什么会这样?
答案 0 :(得分:3)
在Java中,您不必编写@Override
来覆盖具有相同签名的方法。它就像默认。在C#中情况并非如此,因为必须前缀virtual
(public virtual void mailCheck()
)以表示该方法将被覆盖。
这就是为什么你在两种语言之间获得不同的输出。
答案 1 :(得分:1)
在C#中,您没有覆盖mailCheck
方法。因为通过将mailCheck
重新定义为Salary
类,就像您在C#中所做的一样,您只需隐藏将基类Employee
中定义的函数转换为Salary
派生类。那么下面的代码将不起作用;
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
e.mailCheck();
因为mailCheck
是hidden
到Salary
基类,e.mailCheck
将调用基类实现而不是派生类实现。
为了使用派生类实现,您有两个选择:
第一个选项:
您需要在声明为explicity的变量上显式调用mailCheck
为Salary
类型,然后您需要更改代码:
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
((Salary)e).mailCheck();
// Or just like this:
Salary e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
e.mailCheck();
第二个选项:
就像我已经说过的那样,重新实现基类方法并不意味着你将它重写到派生类中。您只是隐藏此方法。这就是为什么在将代码编译到Visual Studio中时,您将不是错误,而是来自VS 的警告,告诉您需要通过使用显式隐藏此重新实现的方法new
关键字。 new
关键字会告诉其他开发人员将来会查看您的代码,知道您不会隐藏该方法,因为不了解您的内容这样做。
如果您不需要隐藏mailCheck
方法并且需要利用OOP多态性,则必须使用mailCheck
修饰符将virtual
方法标记到基础中,然后必须添加{ {1}}将重新简化的方法修饰为派生类方法。您在override
方法中的代码保持不变。
正如其他人已经说过的那样,Java并不需要你明确地将重新实现的方法标记为覆盖,但是使用C#你需要通过重新实现一个方法来说明你要做什么,否则它只会隐藏它。 / p>