使用接口变量

2023-12-07

我仍在努力更好地理解接口。我知道它们是什么以及如何在课堂上实现它们。

我不明白的是,当您创建一个接口类型之一的变量时:

IMyInterface somevariable;

你为什么要这样做?我不明白如何像类一样使用 IMyInterface...例如调用方法,所以:

somevariable.CallSomeMethod();

为什么要使用 IMyInterface 变量来执行此操作?


您不是在创建接口的实例 - 您是在创建实现该接口的实例。

接口的要点在于,它保证无论实现什么,都将提供在其中声明的方法。

所以现在,使用您的示例,您可以:

MyNiftyClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something nifty
    }
}

MyOddClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something odd
    }
}

现在你有:

IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()

调用 CallSomeMethod 方法现在要么会做一些漂亮的事情,要么会做一些奇怪的事情,当您使用 IMyInterface 作为类型进行传递时,这变得特别有用。

public void ThisMethodShowsHowItWorks(IMyInterface someObject)
{
    someObject.CallSomeMethod();
}

现在,根据您是否使用漂亮的类或奇怪的类调用上述方法,您会得到不同的行为。

public void AnotherClass()
{
    IMyInterface nifty = new MyNiftyClass()
    IMyInterface odd = new MyOddClass()

    // Pass in the nifty class to do something nifty
    this.ThisMethodShowsHowItWorks(nifty);

    // Pass in the odd class to do something odd
    this.ThisMethodShowsHowItWorks(odd);

}

EDIT

这解决了我认为您想要的问题:为什么要将变量声明为接口类型?

也就是说,为什么使用:

IMyInterface foo = new MyConcreteClass();

优先于:

MyConcreteClass foo = new MyConcreteClass();

希望您清楚为什么在声明方法签名时要使用该接口,但这留下了有关本地作用域变量的问题:

public void AMethod()
{
    // Why use this?
    IMyInterface foo = new MyConcreteClass();

    // Why not use this?
    MyConcreteClass bar = new MyConcreteClass();
}

通常没有技术原因说明为什么该接口是首选。我通常使用该界面是因为:

  • 我通常注入依赖项,因此需要多态性
  • 使用接口清楚地表明了我只使用接口成员的意图

一个你会去的地方技术上需要接口是您利用多态性的地方,例如使用工厂或(正如我上面所说的)使用依赖注入创建变量。

借用 itowlson 的一个例子,使用具体声明你不能这样做:

public void AMethod(string input)
{               
    IMyInterface foo;

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

使用接口变量 的相关文章

随机推荐

  • Android Studio 0.2.6 和 ZBar 项目设置

    我使用的是最新的Android Studio 0 2 6和最新的ZBar Android SDK 到目前为止我所做的 创建了一个名为 QRTest 的全新项目 在我的项目中创建了一个名为 libs 的文件夹 将Zbar libs目录的内容放
  • 如何在不看到权限屏幕的情况下登录 OneDrive(首次登录后)

    我刚刚开始使用 OneDrive API 及其附带的示例程序 OneDriveApiBrowser 正如预期的那样 我第一次登录时 使用 登录到 MSA 系统要求我提供凭据 我的 2 因素代码 最后出现一个权限屏幕 询问我是否批准应用程序想
  • iOS - Google AdMob v6.12.0 - “idfa 类丢失,不会收集 idfa”

    我在 iOS 8 目标 iOS 7 中的一个项目中使用 Google AdMob DFP 和中介插页式广告 尽管我已经包含了我认为 AdMob v6 12 0 所需的所有框架 根据 AdMob 网站 但我在 Xcode 中看到以下警告消息
  • 构建配置特定资源(调试与发布)

    有谁知道一种聪明的方法 最好使用 Eclipse ADT 工作流程 根据项目是调试还是发布构建 即在 Eclipse 中应用程序是运行还是导出 将特定资源应用于项目 我们经常遇到的常见用例是 API 密钥 如地图 最好建立一个项目 专门为所
  • 将多行分组并连接为一行

    我想将所有 文本 行 连接 成一行并得到一行作为结果 这可能吗 我使用 MSSQL Server 2005 使用 FOR XML 路径 SELECT Text AS text FROM table FOR XML PATH 另一种选择 使用
  • 将相机限制在地面覆盖层上?谷歌地图 Android API v2

    我正在尝试向我的用户显示带有标记的地面覆盖层 我试图将视图限制为仅显示地图上的此图像 我希望用户只能将图像视为放置在地图上的地面叠加层 而无法转到周围的地图 如果他们越过边缘 手势就会被阻止 我想要这样的东西 我不想要这个 仅显示地面覆盖地
  • 如何在实践中创建幽灵小工具?

    我正在开发 NASM GCC 针对 ELF64 PoC它使用一个幽灵小工具来测量访问一组缓存行的时间 冲洗 重新加载 如何制作一个可靠的幽灵小工具 我相信我理解 FLUSH RELOAD 技术背后的理论 但在实践中 尽管有一些噪音 我无法生
  • 使用 BinaryFormatter 反序列化加密数据时出现问题

    这是我的代码 public static void Save
  • 控制 C 或 C++ 中的 shell 命令行通配符扩展

    我正在用 C 编写一个程序 foo 它通常在命令行上调用 如下所示 foo txt My main 以正常方式接收参数 在许多系统上 argv 1 从字面上看是 txt 并且我必须调用系统例程来进行通配符扩展 然而 在 Unix 系统上 s
  • 如何将 Handbrake 输出同时输出到屏幕和文件?

    因此 我一直在使用 Handbrake 命令行对我的视频收藏进行编码以存储在我的 NAS 上 这样我就可以在我的 HTPC 上使用它 我一直在寻找一种既可以输出到屏幕的方法 这样我就可以在编码时观察它的输出 也可以输出到文件 这样我就可以返
  • 非递归快速排序

    我很想知道我的非递归快速排序算法的实现是否存在一些缺点或隐藏的问题 为了优化它应该修改什么 以我的方式比较两个对象时可能会发生什么问题 public class QuickSort
  • MS Access 中出现“操作必须使用可更新查询”错误

    当我尝试运行 SQL 时 收到一条错误消息 操作必须使用可更新查询 据我了解 当 MS Access 中的更新 删除查询中使用联接时 就会发生这种情况 然而 我有点困惑 因为我的数据库中有另一个几乎相同的查询 它工作得很好 这是我的麻烦查询
  • Hadoop java.io.IOException:Mkdirs 无法创建 /some/path

    当我尝试运行我的作业时 出现以下异常 Exception in thread main java io IOException Mkdirs failed to create some path at org apache hadoop u
  • 如何使用 PHP 从 JSON 访问另一个对象内部的类成员

    我有一个像这样的 JSON 字符串 test var1 null var3 null status code 150 message blah blah 我想访问函数中的状态代码 这就是我尝试过的 responseObj jsonServi
  • UNIX 将 LARGE csv 导入 SQLite

    我有一个 5gig csv 文件 也可以作为 sas 数据文件 如果会更容易的话 我需要将其放入 sql 数据库中 以便我可以在 R 中使用它 变量名称全部包含在第一观察行中并用双引号引起来 有 1000 多个变量 其中一些是数字 另一些是
  • 向 UTL_MAIL.SEND 提供凭据以绕过 ORA-29278

    我正在尝试使用 UTL MAIL Send 打包过程从 PL SQL 程序发送电子邮件 但我收到以下错误 ORA 29278 SMTP 瞬时错误 421 服务不可用 我在网上搜索了一下 发现出现这个错误是因为运行我的Oracle数据库的主机
  • UIPickerView 用于具有不同数组的每个文本字段(Swift/Firebase)

    我正在尝试创建一个表单 其中每个文本字段都有一个 UIPickerView 用户可以使用它来选择所需的选项 我需要为每个文本字段使用不同的信息数组 但我似乎无法让它工作 而且我已经坚持了很长一段时间了 我有一个可能有效的方法 但由于每个字段
  • SVG 数据图像不能用作伪元素中的背景图像

    我将 SVG 设置为background image对于伪元素 content position absolute right 0 bottom 0 left 0 width 100 height 12px background image
  • ZXing - 使用通用类型 BarcodeWriter 需要 1 个类型参数 ZXing.NET.Mobile

    我一直在尝试使用 ZXing Net Mobile 和 ZXing Net Mobile Forms 生成 QRCode https github com Redth ZXing Net Mobile并遇到以下错误 严重性代码描述项目文件行
  • 使用接口变量

    我仍在努力更好地理解接口 我知道它们是什么以及如何在课堂上实现它们 我不明白的是 当您创建一个接口类型之一的变量时 IMyInterface somevariable 你为什么要这样做 我不明白如何像类一样使用 IMyInterface 例