现在我正在研究接口,无法理解一些接口实现的东西。例如,我有一些代码:
IModelDoc2 swModel; //IModelDoc2 is an interface. What are we doing here?
boolstatus = swModel.Extension.SelectByID2(.....); //Some parameters
我无法理解如何通过从接口调用来实现此方法。类可以实现接口,我们可以从类调用方法。对?但是我们如何从接口实现方法?
答案 0 :(得分:3)
实现接口成员有两种方法:显式和隐式:
显式:http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx
隐含:http://msdn.microsoft.com/en-us/library/aa664590%28v=vs.71%29.aspx
显式的明显好处是:如果某个变量/成员的编译时类型(声明类型)是实现接口的类,则无法直接调用显式实现的成员,您需要这样做的接口引用。但是你不应该强制尝试将类或结构变量强制转换为接口类型。相反,您应该正确使用界面使用的模式。接口是一个功能强大的抽象工具,它允许从知道实现中抽象出一些代码。这意味着这部分代码应该与实现无关,并且永远不会接收实现接口的结构对象的类引用,它应该只接收接口指针:
interface MyInterface {
void MyMethod(/*...*/);
int MyOtherMethod(/*...*/);
string MyProperty { get; set; }
}
class MyImplementation : MyInterface {
// explicit implementations:
void MyInterface.MyMethod (/*...*/) { /* ... */ }
string MyInterface.MyProperty { get { return /*...*/; } set { something = value; /*...*/ } }
// or even implicit:
public int MyOtherMethod(/*...*/) { /* ... */ return /*...*/; }
// Now, even you may have some public (better be internal) members,
// they should not be used in implementation-agnostic code
internal void SomeNonInterfaceMethod(/*...*/) { /*...*/ }
}
//...
MyInterface myImplementation = new MyImplementation(/*...*/);
// NOT MyInterface myImplementation = new MyImplementation(/*...*/);
//...
//some implementation-agnostic method:
void SomeUsingMethod(MyInterface implementation) { // NOT MyImplementation implementation
// it would kill the abstraction
implementation.MyMethod(/*...*/);
implementation.MyProperty = "some value";
// but you cannot call
// implementation.SomeNonInterfaceMethod(/*...*/); // won't work
// if somewhere you need to do this
MyImplementation violatedEncapsulationImplementation = (MyImplementation)implementation; // AVOID IT!
violatedEncapsulationImplementation.SomeNonInterfaceMethod(/*...*/); // AVOID IT!
// it would work, but it would be an indication of wrong code design
}
现在,您知道基本想法。
答案 1 :(得分:1)
所有接口都是......最简单的形式......是类的实现。接口提供的一个重要好处(对我而言)是解耦代码......实质上它会使您的代码更少依赖于其他类。
示例情况。
假设您有3种不同的货币,美元,印度卢比和欧元。如果没有接口,您将拥有此代码。
UsDollar currency1 = new UsDollar();
使用各自的课程。如果您想换掉UsDollar作为卢比,您必须更换代码/进行必要的更改以支持下一堂课
Rupee currency1 = new Rupee();
但是通过使用接口,您可以解除对所使用的特定类的依赖关系,并使用该接口(类似于您发布的示例代码段的方式)。
所以说你有一个实现CurrencyValue整数的接口和一个汇率方法
public interface ICurrency
{
int CurrencyValue { get; set; }
void ExchangeRate(double percent);
}
然后,您将拥有从接口继承的以下3个类。请记住,如果一个类继承自该接口,则它们必须实现与接口实现的相同。
public class UsDollar : ICurrency
{
public int CurrencyValue { get; set; }
public void ExchangeRate(double percent)
{
Console.WriteLine("Your Exchange Rate for Us Dollar is {0}", CurrencyValue * percent);
}
}
public class Euro : ICurrency
{
public int CurrencyValue { get; set; }
public void ExchangeRate(double percent)
{
Console.WriteLine("Your Exchange Rate for Euro is {0}", CurrencyValue * percent);
}
}
public class Rupee : ICurrency
{
public int CurrencyValue { get; set; }
public void ExchangeRate(double percent)
{
Console.WriteLine("Your Exchange Rate for Rupee is {0}", CurrencyValue * percent);
}
}
所以改变你的用法
Rupee currency1 = new Rupee();
要
ICurrency currency1 = new Rupee();
使用此类的代码不再关心它是卢比,美元,欧元......还是您最终创建的其他任何货币类别。
接口也可以提供各种设计模式的价值(因子模式)。
示例用法:
ICurrency currency1 = new UsDollar();
ICurrency currency2 = new Euro();
ICurrency currency3 = new Rupee();
currency1.CurrencyValue = 10;
currency2.CurrencyValue = 13;
currency3.CurrencyValue = 16;
currency1.ExchangeRate(1.1);
currency2.ExchangeRate(1.6);
currency3.ExchangeRate(1.5);
所以回答你的问题
IModelDoc2 swModel; //IModelDoc2 is an interface. What are we doing here?
这应该特别是创建一个类类型的新对象(在我的例子中,这将与ICurrency currency1 = new UsDollar();)相同。因此,在代码中的某个位置,您可以将值赋给swModel,这将是从IModelDoc2继承的某些类/类型。
希望这有助于/澄清事情。
但是要阅读接口我会建议链接:
http://msdn.microsoft.com/en-us/library/87d83y5b%28v=vs.80%29.aspx
答案 2 :(得分:0)
您必须了解多态性才能理解调用代码所看到的内容与实际实现所做的内容之间的区别。
实现必须有一个实现该接口的实际类(忽略边缘情况)。
调用只能看到一个接口,但该变量的实际类型必须是实现该接口的某个类。
你的例子:
IModelDoc2 swModel; //IModelDoc2 is an interface. What are we doing here?
boolstatus = swModel.Extension.SelectByID2(.....); //Some parameters
甚至不会编译,因为swModel
未初始化。
正确的代码是
IModelDoc2 swModel = new SomeClassImplementingIModelDoc2();
boolstatus = swModel.Extension.SelectByID2(.....); //Some parameters