Language agnostic “这对”意味着什么;编程到一个接口;?

Language agnostic “这对”意味着什么;编程到一个接口;?,language-agnostic,oop,interface,Language Agnostic,Oop,Interface,我已经见过几次提到这一点,我不清楚这是什么意思。你什么时候为什么要这样做 我知道接口是做什么的,但我不清楚这一点,这让我觉得我错过了正确使用它们的机会 如果你要做的是: IInterface classRef = new ObjectWhatever() 您可以使用实现IInterface的任何类?你什么时候需要这样做?我能想到的唯一一件事是,如果您有一个方法,并且您不确定将传递什么对象,除了它实现IInterface。我想不出你需要多久做一次 另外,如何编写一个方法来接收实现接口的对象?这可

我已经见过几次提到这一点,我不清楚这是什么意思。你什么时候为什么要这样做

我知道接口是做什么的,但我不清楚这一点,这让我觉得我错过了正确使用它们的机会

如果你要做的是:

IInterface classRef = new ObjectWhatever()
您可以使用实现
IInterface
的任何类?你什么时候需要这样做?我能想到的唯一一件事是,如果您有一个方法,并且您不确定将传递什么对象,除了它实现
IInterface
。我想不出你需要多久做一次


另外,如何编写一个方法来接收实现接口的对象?这可能吗?

您应该研究控制反转:

在这种情况下,您不会这样写:

IInterface classRef = new ObjectWhatever();
你可以这样写:

IInterface classRef = container.Resolve<IInterface>();
public void DoSomethingToAnObject(IInterface whatever) { ... }
这直接插入到“与做特定事情的对象对话”中。上面定义的方法知道对对象的期望,它实现了接口中的所有内容,但它不关心它是哪种类型的对象,只关心它遵守契约,这就是接口

例如,你可能对计算器很熟悉,在你的生活中可能用过不少,但大多数时候它们都是不同的。另一方面,你知道一个标准计算器应该如何工作,所以你可以使用它们,即使你不能使用每个计算器都没有的特定功能

这就是界面之美。您可以编写一段代码,它知道它将获得传递给它的对象,它可以期望从中获得某些行为。它一点也不关心它是什么类型的对象,只关心它支持所需的行为

让我给你举个具体的例子

public interface IPricable
{
    int Price { get; }
}

public interface ICar : IPricable

public abstract class Article
{
    public int Price { get { return ... } }
}

public class Car : Article, ICar
{
    // Price does not need to be defined here
}
我们有一个为windows窗体定制的翻译系统。该系统通过表单上的控件进行循环,并在每个控件中翻译文本。系统知道如何处理基本控件,如-type-of-control-that-has-Text-property和类似的基本内容,但对于任何基本的东西,它都不够

现在,由于控件继承自我们无法控制的预定义类,我们可以做以下三件事之一:

  • 为我们的翻译系统构建支持,以专门检测它使用的控件类型,并翻译正确的位(维护噩梦)
  • 将支持构建到基类中(不可能,因为所有控件都继承自不同的预定义类)
  • 添加接口支持

  • 所以我们做了3号。我们所有的控件都实现了ILocalizable,这是一个接口,它为我们提供了一种方法,能够将“自身”翻译成翻译文本/规则的容器。因此,表单不需要知道它找到了哪种类型的控件,只需要知道它实现了特定的接口,并且知道有一种方法可以调用来本地化控件。

    您应该研究控制反转:

    在这种情况下,您不会这样写:

    IInterface classRef = new ObjectWhatever();
    
    你可以这样写:

    IInterface classRef = container.Resolve<IInterface>();
    
    public void DoSomethingToAnObject(IInterface whatever) { ... }
    
    这直接插入到“与做特定事情的对象对话”中。上面定义的方法知道对对象的期望,它实现了接口中的所有内容,但它不关心它是哪种类型的对象,只关心它遵守契约,这就是接口

    例如,你可能对计算器很熟悉,在你的生活中可能用过不少,但大多数时候它们都是不同的。另一方面,你知道一个标准计算器应该如何工作,所以你可以使用它们,即使你不能使用每个计算器都没有的特定功能

    这就是界面之美。您可以编写一段代码,它知道它将获得传递给它的对象,它可以期望从中获得某些行为。它一点也不关心它是什么类型的对象,只关心它支持所需的行为

    让我给你举个具体的例子

    public interface IPricable
    {
        int Price { get; }
    }
    
    public interface ICar : IPricable
    
    public abstract class Article
    {
        public int Price { get { return ... } }
    }
    
    public class Car : Article, ICar
    {
        // Price does not need to be defined here
    }
    
    我们有一个为windows窗体定制的翻译系统。该系统通过表单上的控件进行循环,并在每个控件中翻译文本。系统知道如何处理基本控件,如-type-of-control-that-has-Text-property和类似的基本内容,但对于任何基本的东西,它都不够

    现在,由于控件继承自我们无法控制的预定义类,我们可以做以下三件事之一:

  • 为我们的翻译系统构建支持,以专门检测它使用的控件类型,并翻译正确的位(维护噩梦)
  • 将支持构建到基类中(不可能,因为所有控件都继承自不同的预定义类)
  • 添加接口支持

  • 所以我们做了3号。我们所有的控件都实现了ILocalizable,这是一个接口,它为我们提供了一种方法,能够将“自身”翻译成翻译文本/规则的容器。因此,表单不需要知道它找到了哪种控件,只需要知道它实现了特定的接口,并且知道有一种方法可以调用来本地化控件。

    对接口编程就是说,“我需要这个功能,我不在乎它来自何方。”

    考虑(在Java中,
    List
    接口与
    ArrayList
    LinkedList
    具体类的对比。如果我所关心的是,我有一个包含多个数据项的数据结构,我应该通过迭代访问这些数据项,那么我会选择一个
    列表(这是99%的时间)。如果我知道我需要从列表的任意一端进行固定时间的插入/删除,我可能会选择
    LinkedList
    具体实现(或者更可能的是,使用接口)。如果我知道我需要通过索引进行随机访问,我会选择
    ArrayList<
    
    char charAt(int index)
    int length()
    CharSequence subSequence(int start, int end)
    String toString()
    
    // if I want to add search capabilities to my application and support multiple search
    // engines such as Google, Yahoo, Live, etc.
    
    interface ISearchProvider
    {
        string Search(string keywords);
    }
    
    // if I want to support multiple downloads using different protocols
    // HTTP, HTTPS, FTP, FTPS, etc.
    interface IUrlDownload
    {
        void Download(string url)
    }
    
    // how about an image loader for different kinds of images JPG, GIF, PNG, etc.
    interface IImageLoader
    {
        Bitmap LoadImage(string filename)
    }
    
    interface IZipCodeRepository
    {
        IList<ZipCode> GetZipCodes(string state);
    }
    
    PrintZipCodes(IZipCodeRepository zipCodeRepository, string state)
    {
        foreach (ZipCode zipCode in zipCodeRepository.GetZipCodes(state))
        {
            Console.WriteLine(zipCode.ToString());
        }
    }
    
    Dintf bInst = new Bclass();  
    // now we could call all Dintf functions implemented (defined) in Bclass.
    
    Dintf cInst = new Cclass();  
    // now we could call all Dintf functions implemented (defined) in Cclass.
    
    interface Airplane{
        parkPlane();
        servicePlane();
    }
    
    parkPlane(Airplane plane)
    
    servicePlane(Airplane plane)
    
    public class Fighter implements Airplane {
    
        public void  parkPlane(){
            // Specific implementations for fighter plane to park
        }
        public void  servicePlane(){
            // Specific implementatoins for fighter plane to service.
        }
    }
    
    public class HighFlyer implements Airplane {
    
        public void  parkPlane(){
            // Specific implementations for HighFlyer plane to park
        }
    
        public void  servicePlane(){
            // specific implementatoins for HighFlyer plane to service.
        }
    }
    
    public Class ControlPlane{ 
     AirPlane plane;
     // so much method with AirPlane reference are used here...
    }
    
    JumboJetPlane // implementing AirPlane interface.
    AirBus        // implementing AirPlane interface.
    
    public interface IPricable
    {
        int Price { get; }
    }
    
    public interface ICar : IPricable
    
    public abstract class Article
    {
        public int Price { get { return ... } }
    }
    
    public class Car : Article, ICar
    {
        // Price does not need to be defined here
    }
    
    class Person implements AbstractEmployee, AbstractFriend {
    }
    
    function party() {
        const friend: Friend = new Person("Kathryn");
        friend.HaveFun();
    }
    
    function workplace() {
        const employee: Employee = new Person("Kathryn");
        employee.DoWork();
    }