为什么继承不能按照我认为应该的方式工作?

2024-04-12

我遇到了一些继承问题,因为我有一组相互关联的抽象类,需要一起重写它们才能创建客户端实现。理想情况下,我想做类似以下的事情:

abstract class Animal
{
  public Leg GetLeg() {...}
}

abstract class Leg { }

class Dog : Animal
{
  public override DogLeg Leg() {...}
}

class DogLeg : Leg { }

这将允许任何使用 Dog 类的人自动获取 DogLegs,任何使用 Animal 类的人自动获取 Legs。问题是重写的函数必须与基类具有相同的类型,因此无法编译。我不明白为什么不应该这样做,因为 DogLeg 可以隐式转换为 Leg。我知道有很多方法可以解决这个问题,但我更好奇为什么这在 C# 中不可能/实现。

EDIT:我对此进行了一些修改,因为我实际上在代码中使用属性而不是函数。

EDIT:我将其改回函数,因为答案仅适用于这种情况(属性设置函数的值参数的协方差不应该工作)。对于波动,敬请谅解!我意识到这让很多答案显得无关紧要。


简短的回答是 GetLeg 的返回类型是不变的。长答案可以在这里找到:协变和逆变 http://blogs.msdn.com/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx

我想补充一点,虽然继承通常是大多数开发人员从工具箱中取出的第一个抽象工具,但几乎总是可以使用组合来代替。对于 API 开发人员来说,组合的工作量稍微多一些,但使 API 对于消费者来说更有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么继承不能按照我认为应该的方式工作? 的相关文章

  • 在 C/C++ 中获得正模数的最快方法

    通常在我的内部循环中 我需要以 环绕 方式索引数组 因此 例如 如果数组大小为 100 并且我的代码要求元素 2 则应该给它元素 98 高级语言 例如 Python 可以简单地使用my array index array size 但由于某
  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • 为什么在创建矩阵类时使用向量不好?

    对于我的矩阵类 我做了 template
  • 平滑滚动.net 表单

    您好 我正在 net 中使用表单 并且在运行时动态添加大量链接标签 我将这些链接标签添加到面板并将该面板添加到 winform 当链接标签的数量增加时 表单会显示一个自动滚动条 垂直 现在 当我使用自动滚动向下滚动时 表单在滚动时不会更新其
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • 类特定的新删除运算符是否必须声明为静态

    标准中是否要求类特定的 new new delete 和 delete 是静态的 我可以让它们成为非静态成员运算符吗 为什么需要它们是静态的 它们被隐式声明为静态 即使您没有键入 static
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • C# 构建一个 webservice 方法,它接受 POST 方法,如 HttpWebRequest 方法

    我需要一个接受 POST 方法的 Web 服务 访问我的服务器正在使用 POST 方法 它向我发送了一个 xml 我应该用一些 xml 进行响应 另一方面 当我访问他时 我已经使用 HttpWebRequest 类进行了管理 并且工作正常
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • 是否有相当于 Clang/LLVM 的 .spec 文件,在哪里可以找到参考?

    The gcc驱动程序可以配置为使用特定的链接器 特定的选项和其他细节 例如覆盖系统头 specs files 当前 截至撰写本文时 GCC 版本 4 9 0 的手册此处描述了规范文件 https gcc gnu org onlinedoc
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft

随机推荐

  • Swift 4:Firebase 时间戳

    我应该如何将 Firebase 时间戳与本地设备时间进行比较 let serverTIme FIRServerValue timestamp let localtime Date let dbRef FirebaseServerRefere
  • TypeScript 中的 WebView 扩展

    在代码示例 catcoding 中 支持 webview 逻辑被编写为 JavaScript 中的匿名函数 但我想在 Typescript 中构建此支持逻辑 我厌倦了用 requireJS 将这个逻辑重现为打字稿包 但我无法让它工作 Thi
  • 在 C# 中使用 CreateRemoteThread 传递多个参数

    我的目标是使用 C 中的 P Invoke CreateRemoteThread 调用远程进程中的函数 问题是该函数需要多个参数 有没有办法将多个参数传递给函数 DllImport kernel32 dll SetLastError tru
  • 编译时常量 id

    鉴于以下情况 template
  • 如何限制“v-for”中元素的迭代

    我正在构建一个小型应用程序Vuejs 2 0我有大约 15 个迭代元素 我想限制v for仅 5 个元素 并且可以有更多按钮来显示整个列表 有没有可能 你可以试试这个代码 div div div div div div div div
  • sort 如何计算出有多少 RAM?

    If I do ulimit v 200000 和跑步 sort largefile 我可以看到从top该类型最多使用 142232 Virt 和 92764 Res 但一段时间后会减少更多 sort 如何知道 ulimit 限制设置为多少
  • 将位图加载到 PictureBox 控件

    由于某种原因 这不起作用 我不知道为什么 objBitmap new Bitmap Resource1 im Stream stream objBitmap Save stream ImageFormat Bmp this pictureB
  • Nodejs:返回异步结果的结果

    我正在尝试在 Node js 中编写一个 RESTful API 它基本上围绕控制器 模型模式 并且我遇到了一些关于 Node js 异步性质的问题 Station js 控制器 use strict var url require url
  • 如何使用 Express 框架发出 AJAX 请求?

    我想使用 Express 发送 AJAX 请求 我正在运行如下所示的代码 var express require express var app express app get function req res here I would l
  • 如何实时返回鼠标坐标?

    我是 PyQt 的新手 我正在尝试使用它来创建一个实时返回鼠标位置的小部件 这是我所拥有的 import sys from PyQt5 QtWidgets import QWidget QToolTip QPushButton QAppli
  • scrollIntoView() 在 Chrome 中的多个元素上使用 smooth 函数

    element scrollIntoView行为设置为smooth在 Chrome 中没有像我预期的那样工作 当它仅用于调用堆栈中的一个元素时 它可以正常工作 但如果它用于多个元素 则只有最后一个元素会实际滚动 这在 Firefox 中运行
  • 从 sef url 中删除组件部分,菜单项未完全删除

    我为 joomla 2 5 构建了一个自定义组件 现在我想实现 sef url 所以我开始创建router php文件 我几乎成功了 我唯一想要更改的是删除组件名称链接 这是我得到的 http host tld component comp
  • 如何获得内置 .net 类的漂亮类图?

    要获得概述CodeDom 类 http msdn microsoft com en us library system codedom compiler aspx在 Net 中 我尝试使用 Visual Studio 2010 内置类设计器
  • 如何在Java中将表格数据格式化为文本?

    我想从任意数据集对象模型生成格式良好的表格文本 Java 有没有一个好的库可以做到这一点 具体来说 我希望输出的格式类似于命令行数据管理工具 例如 mysql 的 CLI 例子 Field Type Null Key Default Ext
  • CSS:水平和垂直居中文本? [复制]

    这个问题在这里已经有答案了 我正在创建一个新网站 我需要了解一些信息 将通过示例显示 可以说我这样做了 html div ul li content li li content li li content li li content li
  • switch 语句中的 String 为何比相应的 if-else 语句更高效?

    Java 文档 http docs oracle com javase 7 docs technotes guides language strings switch html says Java 编译器从使用 String 对象的 swi
  • 无法修改 Controls 集合,因为控件包含代码块(即 <% ... %>)

    我正在尝试在 C 中创建动态元标记 但出现以下错误 无法修改 Controls 集合 因为控件 包含代码块 即 这是我添加的代码 HtmlMeta meta new HtmlMeta meta Name keywords meta Cont
  • 捕获 IllegalArgumentException 的最佳方法是什么

    什么时候最好使用这种类型的异常 如果捕获到这样的异常 是否可以正确处理它 catch Exception e 还是需要明确捕获 catch IllegalArgumentException e It would会被第一个捕获 但许多其他异常
  • 如何传入带有泛型类型参数的 func?

    我喜欢向方法发送通用类型转换器函数 但我不知道该怎么做 这是无效的语法 解释了我想要实现的目标 问题是我不知道如何与我的 func 一起指定泛型类型 public void SomeUtility Func
  • 为什么继承不能按照我认为应该的方式工作?

    我遇到了一些继承问题 因为我有一组相互关联的抽象类 需要一起重写它们才能创建客户端实现 理想情况下 我想做类似以下的事情 abstract class Animal public Leg GetLeg abstract class Leg