c# - 有继承问题的重载
问题描述
我有以下代码,它运行成功。但仔细注意它的输出:
using System;
class Base
{
public int f(int i)
{
Console.Write("f (int): ");
return i + 3;
}
}
class Derived : Base
{
public double f(double i)
{
Console.Write("f (double) : ");
return i+3.3;
}
}
class MyProgram
{
static void Main(string[] args)
{
Derived obj = new Derived();
Console.WriteLine(obj.f(3));
Console.WriteLine(obj.f(3.3));
Console.ReadKey(); // write this line if you use visual studio
}
}
输出: f(双):6.3 f(双):6.6 预期输出: f(整数):6 f(双):6.6
这里它只调用派生类方法。但是,如果我稍微改变一下这个程序,如下所示,那么输出是意外的。然后我尝试了一些东西,我认为这是类型的优先顺序。当我将 Base 类从 int 交换为 double 并将 Derived 类从 double 交换为 int 时,预期的输出为真。
using System;
namespace MyProgram
{
class Base
{
public double f(double i)
{
Console.Write("f (double): ");
return i + 3.3;
}
}
class Derived : Base
{
public int f(int i)
{
Console.Write("f (int): ");
return i + 3;
}
}
class Program
{
static void Main(string[] args)
{
Derived obj = new Derived();
Console.WriteLine(obj.f(3));
Console.WriteLine(obj.f(3.3));
}
}
}
输出: f(整数):6 f(双):6.6
怎么可能?
解决方案
在第一个示例中,编译器可以在数字类型(int
to double
)之间进行简单的类型转换。这使得该f(double)
函数成为可能的调用目标。编译器会尽可能在派生类上调用函数,因为派生类可能包含更具体的逻辑。基类可能包含更多通用逻辑,因此价值较低。
在第二个示例中,派生类上的函数只能使用int
参数调用。编译器选择这个函数是因为它在派生类上,即使基类上的函数也可能有效。当参数为 a 时,基类上的函数是唯一的选项double
。
推荐阅读
- azure-synapse - 如何通过 Synapse 的 Spark 池将数据帧数据附加到专用的 SQL 池中?
- thymeleaf - 如何将身份验证原则值设置为变量
- javascript - 等待最后一个 ajax 请求在复杂链中解析
- mysql - 为什么我需要为 MySQL 8 禁用“foreign_key_checks”才能在添加外键时使用 INPLACE 算法?
- mysql - mysql 问题:在 Apple Silicon M1 mini 上升级到 Mac OS X 11.6 后,无法连接
- powershell - 编写一个 power shell 脚本来维护最新的 5 个版本并删除目录中的所有其他时间戳版本
- java - 如何使用 LdapTemplate 通过 memberOf 搜索 LDAP 实体
- maven - Maven 依赖项仅限于私有存储库
- python - Jinja 将渲染的 html 转换为图像
- c++ - 如何使用分配器来改变向量值?