我正在尝试提前学习OOP概念。我正在阅读主题界面,并有一个混乱。但首先,让我告诉你究竟是什么导致了这种混乱 我测试了这个Code Sample。但我对接口的使用感到困惑。在实现该代码之后,在我看来,我可以通过简单地创建它的实例来从类A调用方法DoFirst。那么为什么要在第一时间使用界面呢?
这样的事情:
A myA = new A();
myA.DoFirst();
并且相似,
B myB = new B();
myB.DoFirst();
在这两个类中,我必须实现一个名为'DoFirst'的方法,那么接口提供给我的是什么好处?
我不能自己在不同的课程中编写这些方法吗?
我的第二个问题,说我有一个有5种方法的界面。如果一个类实现它,并且只想提供3个方法的实现,而不是编写接口提供的所有5个方法的代码。这不是没用的吗?为什么有我不想要的访问方法?
有人可以用例子(高度赞赏)回答这些吗?
答案 0 :(得分:3)
您提供的链接中已经指出了优势...... 基本上你也可以写
void DoSomething(IMyInterface obj)
{
obj.DoFirst();
}
然后将实现该接口的任何类型的对象作为参数发送。
A myA = new A();
DoSomething(myA);
B myB = new B();
DoSomething(myB);
方法DoSomethig
不关心对象的类型,只要它公开名为IMyInterface
的接口。
答案 1 :(得分:3)
一些真实生活示例 - 也是使用界面的另一种方式/原因。
在我自己的代码中,我有一个Engine,它处理代码以在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();
}
答案 2 :(得分:0)
C#是一种静态类型语言(至少除非你明确告诉它不是)。这意味着编译器使用变量的类型来知道引用的对象是否具有您将要使用的成员。
因此,接口为编译器(以及其他程序员)提供了一个契约,即该类实现该接口。因为接口可以在没有层次关系的类之间共享,这意味着您可以通过在参数类型中定义该接口来定义可以将对象作为参数的方法。