通过接口访问对象

Accessing objects through their interfaces

这到底是什么意思?我正在阅读设计模式书。它说 对象只能通过它们的接口访问,我无法理解它,有人能给我一个例子吗(如果它在 C# 中,我会非常感激)

我们使用它真正实现了什么?

谢谢

如果您有一个名为 Espson 的 class 并且它实现了一个名为 IPrinter 的接口,那么您可以通过它的接口实例化该对象。

IPrinter printer = new Espson();

Epson 可能有许多不属于 IPrinter 接口的方法,但您可能并不关心。您可能想要做的就是调用 IPrinter 接口中定义的方法 Print

然后我可以将 class 传递给一个名为 PrintDocument(IPrinter printer) 的方法,该方法不关心它是什么类型的打印机,它只知道它有一个名为 [=15 的方法=]

这真的取决于。如果变量的类型是"interface",那么在这种情况下,对象只能通过接口类型访问。

让我们考虑一个例子——假设我有一个定义如下的接口——

interface IMyInterface
{
   string B();
}

如果我使用 class "MyClass" 实现此接口,如下所示 -

public class MyClass:IMyInterface
   {
      public string B()
      { 
           return "In Class";
      }
   }

   public class MyAnotherClass:IMyInterface
       {
          public string B()
          { 
               return "In Another Class";
          }
       }

我使用如下所示的界面创建了 class 的实例

   IMyInterface myinst = new MyClass();

然后在上述情况下,我只能使用变量 myinst 访问方法 B(),其中包含对 MyClass 的引用类型。

更进一步,假设我有一个采用 IMyInterface 类型参数的方法,如下所示 -

    public class UseOfInterface{
    public void InterfaceUse(IMyInterface myPara)
    {
      myPara.B();
    }
}

我调用这个方法如下所示 -

        IMyInterface myInst = new MyClass();
        IMyInterface myAnotherInst = new MyAnotherClass();

        UseOfInterface interfaceUse = new UseOfInterface();
        interfaceUse.InterfaceUse(myInst); // returns "In Class"
        interfaceUse.InterfaceUse(myAnotherInst); // returns "In Another Class"

然后,如上所示,在运行时决定使用接口变量调用哪个方法。

但是如果我创建了一个 MyClass 类型的变量,它会包含一个 MyClass 类型本身的引用,如下所示 -

   MyClass myinst = new MyClass();

然后可以使用 MyClass 实例访问方法 B()。所以这取决于你正在处理什么类型的场景。

编辑:为什么使用接口?

使用接口的主要原因是它为 class 提供了一个合同,除了 C# 中的多重继承支持之外,它正在为其实现。让我们看一个提供合同的例子。

假设你的程序集中有一个class - "Car"你想公开,class的定义如下所示

namespace CarNameSpace
{
   public class Car()
   {
      public void Drive(IDriver driver)
      {
         if(driver.Age > 18)
         {
            driver.Drive();
         }
      }
   }
}

如上所示,任何实现IDriver接口的人都可以驾驶小车,定义如下,

interface IDriver
{
   string Age{get; set;}
   string Name {get set;}
   string Drive()
}

为了驾驶我的汽车,我会将 IDriver 接口暴露给外部世界,因此任何实现我的接口的人都可以调用 Car 的 Drive 方法,这无关紧要如下图他是怎么开车的

public class PerfectDriver:IDriver
{
   public PerfectDriver()
   {
     Name = "Vikram";
     Age = 30;
   }
   public int Age{get; set;}
   public string Name {get; set;}
   public string Drive()
   {
      return "Drive's perfectly";
   }
}

Carclass可以如下图使用

  PerfectDriver perf = new PerfectDriver
  Car myCar = Car();  
  myCar.Driver(perf);

接口是描述对象 public 成员签名的结构。它包含保证出现在实现该接口的任何对象上的属性、方法和事件的声明(仅声明,没有实现)。

这是一个简单的接口和一些 类 实现它的接口。接口 "INamed" 简单地声明实现该接口的对象有一个 "Name" 属性 是一个字符串。

public interface INamed{
    string Name{get;}
}

public class Person : INamed{
    public string Name{get;set;}
}

public class Place : INamed{
    public string Name{get;set;}
}

public class Thing : INamed{
    public string Name{get;set;}
}

...以及接受该接口类型参数的简单方法。

static void PrintName(INamed namedObject){
    Console.WriteLine(namedObject.Name);
}

此 "PrintName" 方法可以接受实现该接口的任何类型的参数。 "accessing objects by their interface" 的优点是它为您的应用程序注入了一定的灵活性,访问这些接口而不是它们的具体类型允许您对这些对象进行操作而不必知道它们到底是什么。

例如,我可以选择在 IDbCommand 接口上操作,而不是在具体的 SqlCommand 上操作,并且我以这种方式编写的大部分内容在使用各种数据库提供程序时都会很有用。

简单的想法是你不需要知道你是在车里还是在船里,因为你可以用轮子和踏板驾驶任何东西。

问题是接口有多种含义。在这种情况下,作者说的是必须仅通过 public 方法(在 C# 中也通过 public 属性)访问对象。

(当然继承者可以使用受保护的方法)

Public methods/properties 形成 class 的 public 界面。它与 C# 中 interface 关键字描述的接口不同。

接口是指对象向对象的用户公开的内容。一个对象将是 class 的一个实例,它将有自己的接口并可能实现一个或多个其他接口。

虽然 C# 等语言允许您定义称为接口的东西,但它们与通过其接口访问对象的语句中提到的接口不同。例如,在 Scala 这样的语言中,C# 称为接口的东西称为特征。大多数设计模式确实涉及使用已定义的接口,即 public interface <interface name>,但同样,这些与原始声明中的含义不同。

假设我在 C# 中定义了以下 class:

public class MyType
{
  public void Method1()
  {
    ...
  }

  private void Method2()
  {
    ...
  }

  public int Method3()
  {
    ...
  }
}

然后我与 class 交互的接口是它公开的两个方法,void Method1int Method2 以及隐式无参数构造函数。

现在,假设我定义了以下接口和 class:

public interface IInterface1
{
    void Method1();
}

public interface IInterface2
{
    int Method3();
}

public class MyType2 : IInterface1, IInterface2
{
  public void Method1()
  {
    ...
  }

  private void ADifferentMethod()
  {
    ...
  }

  public int Method3()
  {
    ...
  }
}

用户与 MyType2 实例交互的界面与用户与 MyType1 实例交互的界面相同(不同的构造函数除外),因为public 方法(和其他 public 成员)是相同的:void Method1int Method3