【问题标题】:same code but different output c# vs java using polymorphism?相同的代码但不同的输出 c# vs java 使用多态性?
【发布时间】:2016-06-02 05:22:53
【问题描述】:

我在玩多态性概念。我认为所有 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# 中的 virtual,该功能在 Java 中“始终开启”,但在 C# 中是可选的。 Here is why.
  • 在 c# 中查找“覆盖”。
  • @JoachimIsaksson 我知道在 c# 中覆盖,我们可以在 c# 中覆盖虚拟方法。是不是意味着我们不用在java中显式写virtual和override关键字,而在c#中我们必须写这些词来覆盖基类方法?
  • @MOHSIN 没错。如果基类中的方法不是虚拟方法,则不能在子类中覆盖它。
  • @MOHSIN 确切地说,在 Java 中你不需要编写这些。默认是隐含的

标签: java c# overriding virtual


【解决方案1】:

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

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

因为mailCheckhiddenSalary 基类,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 多态性,那么您必须使用 virtual 修饰符将 mailCheck 方法标记到基础中,然后您必须将 override 修饰符添加到重新实现的方法转化为派生类方法。您在 Mainmethod 中的代码保持不变。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 谢谢伙计,明白了;)
    猜你喜欢
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 2020-04-18
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    • 1970-01-01
    相关资源
    最近更新 更多