理解OOP中的接口

本文关键字:接口 OOP 理解 | 更新日期: 2023-09-27 18:00:37

我正在努力学习面向对象的高级概念。我正在通读主题界面,有一种困惑。但首先,让我向您展示究竟是什么导致了这种混乱
我测试了这个代码示例。但我对接口的使用感到困惑。在实现了这些代码之后,在我看来,只需创建一个实例,就可以从类A中调用方法DoFirst。那么,为什么要首先使用接口呢?

类似这样的东西:

A myA = new A();
myA.DoFirst();

类似地,

B myB = new B();
myB.DoFirst();

在这两个类中,我都必须实现一个名为"DoFirst"的方法,那么接口为我提供了什么好处呢?

难道我不能自己在不同的类中编写这些方法吗?

我的第二个问题,假设我有一个有5个方法的接口。如果一个类实现了它,并且只想提供3个方法的实现,而不是编写接口提供的所有5个方法的代码。这不是没用吗?为什么有我不想要的访问方法?

有人能举例回答吗(非常感谢)?

理解OOP中的接口

您提供的链接中已经指出了优势。。。基本上你也可以写

void DoSomething(IMyInterface obj)
{
    obj.DoFirst();
}

然后将实现该接口的任何类型的对象作为参数发送。

A myA = new A();
DoSomething(myA);
B myB = new B();
DoSomething(myB);

方法DoSomethig不关心对象的类型,只要它公开一个名为IMyInterface的接口即可。

一些现实生活中的例子-还有使用接口的另一种方式/原因。

在我自己的代码中,我有一个引擎,它处理代码以在Excel中生成报告。在这个引擎中,我不得不用两种不同的方式编写代码,一种是使用Microsoft Excel Interop,另一种是用Open Office Interop。我实现了一个接口,而不是复制我的整个引擎以两种不同的方式工作,或者在所有实际的互操作函数中编写大量if语句。然后我声明了两个类,每个类实现接口,但一个使用Excel,另一个使用开放式办公室。然后,在我的代码中,我简单地引用接口及其函数,并在函数的开头使用一个if语句来告诉接口要实现哪个类。

public class ExcelEngineInterop : ISSinterface
{ ... }
public class OOEngineInterop : ISSinterface
{ ... }
//cant use two variables with the same name, so use 1 interface reference instead
ISSinterface ssInt;
if(ExcelFlag)
    ssInt = new ExcelEngineInterop();
else
    ssInt = new OOEngineInterop();
//two VERY different functions between Excel and OpenOffice.
ssInt.OpenApp();
ssInt.OpenFile(fileName);
//etc etc and so on

这是使用接口的另一个原因。当您需要一个代码块来根据某些外部标志以两种(或多种)不同的方式进行操作时。

另一个例子。

有一个顶级表单,下面有很多自定义用户控件。用户触发表单级别的事件,比如按钮单击,但根据哪些用户控件处于活动状态以及单击时控件上的设置,控件本身需要做一些不同的事情。与其编写数量惊人的if语句来确保每个语句都能从顶层正确运行,不如在每个控件上实现一个接口,然后这样做:

public ButtonClick(object sender, EventArgs e)
{
    //note: I dont know which of my classes currentrightcontrol belongs to at the moment.
    //      it could be any one of 22 different controls. It must be cast to something
    //      in order to call the ButtonClick method (its actual type is generic "UserControl"
    IMyRunControl ctrl = CurrentRightControl as IMyRunControl;
    ctrl.FormButtonClicked();
}

C#是一种静态类型的语言(至少除非您明确告诉它不要这样做)。这意味着编译器使用变量的类型来知道被引用对象是否具有要使用的成员。

因此,接口为编译器(以及其他程序员)提供了一个契约,该契约是此类实现该接口的。因为接口可以在没有层次关系的类之间共享,这意味着您可以通过在参数类型中定义接口来定义一个可以将对象作为参数的方法。