Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 为什么可以';我似乎不懂界面吗?_Oop_Interface - Fatal编程技术网

Oop 为什么可以';我似乎不懂界面吗?

Oop 为什么可以';我似乎不懂界面吗?,oop,interface,Oop,Interface,有人能帮我揭开界面的神秘面纱,或者给我举一些好的例子吗?我经常看到界面在这里和那里弹出,但我从来没有真正接触过界面的良好解释或何时使用它们 我是在接口与抽象类的上下文中谈论接口。接口是一种强制对象实现一定数量功能的方法,而不必使用继承(这会导致代码的强耦合,而不是通过使用接口实现的松散耦合) 接口描述的是功能,而不是实现。最简单的答案是接口定义了类的功能。这是一份“合同”,上面说你的类将能够做这个动作 Public Interface IRollOver Sub RollOver() E

有人能帮我揭开界面的神秘面纱,或者给我举一些好的例子吗?我经常看到界面在这里和那里弹出,但我从来没有真正接触过界面的良好解释或何时使用它们


我是在接口与抽象类的上下文中谈论接口。

接口是一种强制对象实现一定数量功能的方法,而不必使用继承(这会导致代码的强耦合,而不是通过使用接口实现的松散耦合)


接口描述的是功能,而不是实现。

最简单的答案是接口定义了类的功能。这是一份“合同”,上面说你的类将能够做这个动作

Public Interface IRollOver
    Sub RollOver()
End Interface

Public Class Dog Implements IRollOver
    Public Sub RollOver() Implements IRollOver.RollOver
        Console.WriteLine("Rolling Over!")
    End Sub
End Class

Public Sub Main()
    Dim d as New Dog()
    Dim ro as IRollOver = TryCast(d, IRollOver)
    If ro isNot Nothing Then
        ro.RollOver()
    End If
End Sub

基本上,您可以保证Dog类只要继续实现该接口,就始终具有滚动的能力。如果猫获得了RollOver()的能力,它们也可以实现该接口,并且当要求猫狗滚动()时,您可以对猫狗进行统一处理。

接口允许您根据“描述”而不是类型进行编程,从而允许您更松散地关联软件的元素

可以这样想:你想与你旁边的多维数据集中的某个人共享数据,所以你拿出你的闪存棒并复制/粘贴。你走到隔壁,那家伙说“那是USB吗?”你说是的——一切就绪。闪存棒的大小和制造商无关——重要的是它是USB

同样地,接口允许您对开发进行一般化。使用另一个类比——假设您想要创建一个应用程序,该应用程序可以虚拟地绘制汽车。您可能有这样的签名:

public void Paint(Car car, System.Drawing.Color color)...
public class Fax : ISorteable 
{
   //implement the ISorteable stuff here.
}
这将一直有效,直到你的客户说“现在我想给卡车喷漆”,所以你可以这样做:

public void Paint (Vehicle vehicle, System.Drawing.Color color)...
这将拓宽你的应用程序。。。直到你的客户说“现在我想粉刷房子!”你从一开始就可以做的就是创建一个界面:

public interface IPaintable{
   void Paint(System.Drawing.Color color);
}
public interface IUpdateTracked
{
  DateTime LastUpdated { get; set; }
  int UpdatedByUser { get; set; }
}
…并将其传递给您的日常工作:

public void Paint(IPaintable item, System.Drawing.Color color){
   item.Paint(color);
}

希望这是有意义的-这是一个非常简单的解释,但希望能够触及其核心。

简单地说:接口是一个定义了方法但没有实现的类。相反,抽象类实现了一些方法,但不是全部

当你开朋友的车时,你或多或少知道怎么做。这是因为传统汽车都有一个非常相似的界面:方向盘、踏板等等。将此接口视为汽车制造商和驾驶员之间的合同。作为一名驾驶员(软件术语中界面的用户/客户端),你不需要了解不同汽车的细节就能驾驶它们:例如,你只需要知道转动方向盘就能使汽车转向。作为一个汽车制造商(软件方面接口实现的提供者),你清楚你的新车应该有什么以及它应该如何运行,这样司机就可以使用它们,而无需额外培训。这个契约就是软件设计人员所说的解耦(用户与提供商之间的解耦)--客户端代码是使用接口,而不是接口的特定实现,因此不需要知道实现接口的对象的详细信息。

接口在类和调用接口的代码之间建立契约。它们还允许您拥有类似的类,这些类实现相同的接口,但执行不同的操作或事件,而不必知道您实际使用的是哪一个。作为一个例子,这可能更有意义,所以让我在这里尝试一个

public class SomeDTO : IUpdateTracked
{
  // IUpdateTracked implementation as well as other methods for SomeDTO
}
void SubmitToWorkflow(object o, User u)
{
  IUpdateTracked updateTracked = o as IUpdateTracked;
  if (updateTracked != null)
  {
     updateTracked.LastUpdated = DateTime.UtcNow;
     updateTracked.UpdatedByUser = u.UserID;
  }
  // ...
假设你有两门课,叫做狗、猫和老鼠。这些类中的每一个都是Pet,理论上你可以从另一个名为Pet的类继承它们,但问题是。宠物本身不会做任何事情。你不能去商店买宠物。你可以去买一只狗或猫,但宠物是一个抽象的概念,而不是具体的

所以你知道宠物可以做某些事情。他们可以睡觉,吃东西等等。所以你定义了一个叫做IPet的接口,它看起来像这样(C#语法)

您的每个狗、猫和老鼠类都实现IPet

public class Dog : IPet
所以现在这些类中的每一个都必须有自己的Eat和Sleep实现。耶,你有合同。。。现在重点是什么

接下来,假设您想创建一个名为PetStore的新对象。这不是一个很好的宠物店,所以他们基本上只是卖给你一个随机的宠物(是的,我知道这是一个人为的例子)

问题是你不知道它会是什么类型的宠物。多亏了这个界面,尽管你知道不管它是什么,它都会吃和睡


所以这个答案可能一点帮助都没有,但总的想法是,接口让你做一些简单的事情,比如依赖注入和控制反转,你可以得到一个对象,有一个定义良好的对象可以做的事情列表,而不需要真正知道该对象的具体类型

将接口视为合同。当一个类实现一个接口时,它本质上同意遵守该契约的条款。作为消费者,您只关心您拥有的物品是否能够履行其合同义务。它们的内部工作和细节并不重要。

接口允许您以通用方式针对对象进行编码。例如,假设您有一个发送报告的方法。现在假设你有一个新的需求,你需要写一份新的报告。如果你能重用你已经写过的方法,那就太好了,对吗?接口使这变得简单:

interface IReport
{
    string RenderReport();
}

class MyNewReport : IReport
{
    public string RenderReport()
    {
        return "Hello World Report!";

    }
}

class AnotherReport : IReport
{
    public string RenderReport()
    {
        return "Another Report!";

    }
}

//This class can process any report that implements IReport!
class ReportEmailer()
{
     public void EmailReport(IReport report)
     {
         Email(report.RenderReport());
     }
}

class MyApp()
{
    void Main()
    {
        //create specific "MyNewReport" report using interface
        IReport newReport = new MyNewReport();

        //create specific "AnotherReport" report using interface
        IReport anotherReport = new AnotherReport();

        ReportEmailer reportEmailer = new ReportEmailer();

        //emailer expects interface
        reportEmailer.EmailReport(newReport);
        reportEmailer.EmailReport(anotherReport);



    }

}

下面是一个我经常使用的与数据库相关的示例。假设您有一个对象和一个容器对象,如列表。让我们假设,有时您可能希望以特定的顺序存储对象。假设序列与
ArrayList ar = (ArrayList)SomeIList;
public class Fax : ISorteable 
{
   //implement the ISorteable stuff here.
}
public interface ICommand
{
    void Execute();
}
public class PrintSomething : ICommand
{
    OutputStream Stream { get; set; }
    String Content {get; set;}
    void Execute()
    { 
        Stream.Write(content);
    }
}
INeedFreshFoodAndWater[] array = new INeedFreshFoodAndWater[];
array.Add(new Dog());
array.Add(new Cat());

foreach(INeedFreshFoodAndWater item in array)
{
   item.Feed();
   item.Water();
}
public interface IReport
{
    void RenderReport(); // This just defines the method prototype
}

public abstract class Reporter
{
    protected void DoSomething()
    {
        // This method is the same for every class that inherits from this class
    }
}

public class ReportViolators : Reporter, IReport
{
    public void RenderReport()
    {
        // Some kind of implementation specific to this class
    }
}

public class ClientApp
{
    var violatorsReport = new ReportViolators();

    // The interface method
    violatorsReport.RenderReport();

    // The abstract class method
    violatorsReport.DoSomething();
}
using (DisposableClass myClass = new DisposableClass())
  {
  // code goes here
  }
// First pass - not maintainable
void SubmitToWorkflow(object o, User u)
{
  if (o is StreetMap)
  {
     var map = (StreetMap)o;
     map.LastUpdated = DateTime.UtcNow;
     map.UpdatedByUser = u.UserID;
  }
  else if (o is Person)
  {
     var person = (Person)o;
     person.LastUpdated = DateTime.Now; // Whoops .. should be UtcNow
     person.UpdatedByUser = u.UserID;
  }
  // Whoa - very unmaintainable.
// Second pass - brittle
void SubmitToWorkflow(object o, User u)
{
  if (o is DTOBase)
  {
     DTOBase dto = (DTOBase)o;
     dto.LastUpdated = DateTime.UtcNow;
     dto.UpdatedByUser = u.UserID;
  }
// Third pass pass - also brittle
void SubmitToWorkflow(DTOBase dto, User u)
{
  dto.LastUpdated = DateTime.UtcNow;
  dto.UpdatedByUser = u.UserID;
public interface IUpdateTracked
{
  DateTime LastUpdated { get; set; }
  int UpdatedByUser { get; set; }
}
public class SomeDTO : IUpdateTracked
{
  // IUpdateTracked implementation as well as other methods for SomeDTO
}
void SubmitToWorkflow(object o, User u)
{
  IUpdateTracked updateTracked = o as IUpdateTracked;
  if (updateTracked != null)
  {
     updateTracked.LastUpdated = DateTime.UtcNow;
     updateTracked.UpdatedByUser = u.UserID;
  }
  // ...
// Using an interface to bridge properties
public class LegacyDTO : IUpdateTracked
{
    public int LegacyUserID { get; set; }
    public DateTime LastSaved { get; set; }

    public int UpdatedByUser
    {
        get { return LegacyUserID; }
        set { LegacyUserID = value; }
    }
    public DateTime LastUpdated
    {
        get { return LastSaved; }
        set { LastSaved = value; }
    }
}
// Explicit implementation of an interface
public class YetAnotherObject : IUpdatable
{
    int IUpdatable.UpdatedByUser
    { ... }
    DateTime IUpdatable.LastUpdated
    { ... }
// Decouples the caller and the code as both
// operate only on IList, and are free to swap
// out the concrete collection.
public IList<T> FindDuplicates( IList<T> list )
{
    var duplicates = new List<T>()
    // TODO - write some code to detect duplicate items
    return duplicates;
}
class AnnualRaiseAdjuster
   : ISalaryAdjuster
{
   AnnualRaiseAdjuster(IPayGradeDetermination payGradeDetermination) { ...  }

   void AdjustSalary(Staff s)
   {
      var payGrade = payGradeDetermination.Determine(s);
      s.Salary = s.Salary * 1.01 + payGrade.Bonus;
   }
}
Bird bird = GetMeAnInstanceOfABird(someCriteriaForSelectingASpecificKindOfBird);
bird.Fly(Direction.South, Speed.CruisingSpeed);