相同的代码但不同的输出 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();
因为 mailCheck
是 hidden
到 Salary
基础 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#,您需要通过重新实现一个方法来明确说明您正在尝试做什么,否则您会这样做只会隐藏它。
我一直在研究多态性概念。我认为所有 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();
因为 mailCheck
是 hidden
到 Salary
基础 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#,您需要通过重新实现一个方法来明确说明您正在尝试做什么,否则您会这样做只会隐藏它。