相同的代码,但输出不同的 C# 与使用多态性的 Java

本文关键字:Java 多态性 输出 代码 | 更新日期: 2023-09-27 18:35:27

我在玩多态概念。我认为所有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 中运行此代码,它调用工资类方法,如果我在 c# 中运行此代码,它调用员工类方法。

为什么会这样?

相同的代码,但输出不同的 C# 与使用多态性的 Java

在 Java 中,您不必编写 @Override 即可覆盖具有相同签名的方法。默认情况下是这样的。在 C# 中并非如此,因为您必须添加前缀virtual
public virtual void mailCheck() ) 以指示该方法将被覆盖。

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

在 C# 中,您不会重写 mailCheck 方法。因为通过像在 C# 中那样将mailCheck重新定义为类Salary,您只是将基类中定义的函数隐藏Employee Salary派生类中。那么下面的代码将不起作用;

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

由于mailCheck hidden Salary基类中,因此e.mailCheck将调用基类实现而不是派生类实现。

为了使用派生类实现,您有两个选项:

第一个选项:

您需要在声明为 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();

第二种选择:

正如我已经说过的,重新实现基类方法并不意味着要将其重写到派生类中。你只是隐藏了这种方法。这就是为什么在将代码编译到 Visual Studio 中时,您不会收到错误,而是来自 VS 的警告,告诉您需要使用 new 关键字显式隐藏此重新实现的方法。new关键字将告诉其他开发人员,将来会查看您的代码,知道您不会因为不了解自己在做什么而隐藏该方法。如果您不需要隐藏mailCheck方法并且需要利用 OOP 多变性,则必须使用修饰符将mailCheck方法标记到基virtual然后必须将 override 修饰符添加到派生类方法中。Main方法中的代码保持不变。

正如其他人已经说过的,Java不需要你明确地将重新实现的方法标记为重写,但是使用C#,你需要通过像你一样重新实现一种方法来明确说明你试图做什么,否则它只会隐藏它。