相同的代码但不同的输出 c# vs java 使用多态性?

same code but different output c# vs java using polymorphism?

我一直在研究多态性概念。我认为所有 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 class 方法.

为什么会这样?

在Java中,你不必写@Override in order to override a method with the same signature. It is like that by default. That is not the case in C#, as you have to prefix virtual
(public virtual void mailCheck()) 以表示该方法将被覆盖。

这就是您在两种语言之间得到不同输出的原因。

在 C# 中,您不会覆盖 mailCheck 方法。因为通过将 mailCheck 重新定义为 Salary class 就像您在 C# 中所做的那样,您只是 隐藏 基 class 中定义的函数Employee 转化为 Salary 导出 class。那么下面的代码将不起作用;

Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
e.mailCheck();

因为 mailCheckhiddenSalary 基础 class,e.mailCheck 将调用基础 class 实现而不是派生 class实施。

为了使用派生的 class 实现,您有两个选择:

第一个选项:

您需要在显式声明为 Salary 类型的变量上显式调用 mailCheck 然后您需要像这样更改代码:

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();

第二个选项:

就像我已经说过的那样,重新实现基本 class 方法并不意味着您将其覆盖到派生的 class 中。你只是隐藏这个方法。这就是为什么在将代码编译成 Visual Studio 时,您会得到 而不是错误 而是来自 VS 的 警告告诉 您需要使用 new 关键字明确隐藏此重新实现的方法。 new 关键字将告诉其他开发人员将来会查看您的代码,知道您不会通过不理解你在做什么来隐藏方法。 如果您不需要隐藏 mailCheck 方法并且需要利用 OOP 多态性,那么您必须使用 virtual 修饰符将 mailCheck 方法标记到基础中,然后您必须添加 override 将重新实现的方法修改为派生的 class 方法。 Main 方法中的代码保持不变。

正如其他人已经说过的那样,Java 不需要您明确地将重新实现的方法标记为覆盖,但是对于 C#,您需要通过重新实现一个方法来明确说明您正在尝试做什么,否则您会这样做只会隐藏它。