Interface 有人能举例说明为什么在代码重用、松散耦合和;多态性?

Interface 有人能举例说明为什么在代码重用、松散耦合和;多态性?,interface,polymorphism,abstract-class,encapsulation,loose-coupling,Interface,Polymorphism,Abstract Class,Encapsulation,Loose Coupling,关于这个问题已经进行了多次讨论。但我正在寻找一个令人满意的好答案,即以下oops概念。 A.代码重用 B松耦合 C多态性 如果有人能够解释(通过一些使用上述指定技术的示例)何时使用接口以及何时使用抽象类松耦合意味着封装的组件对彼此的了解刚好足以完成任务-不多也不少。对于系统来说,这是一个很好的特性,因为松散耦合的组件可以更改其实现,而对系统的其他依赖组件几乎没有影响。这提高了系统的可维护性 让我们以迭代器为例。迭代器是允许一个元素一个元素地遍历容器的对象。迭代器可能有多种实现: 列表迭代器 向量

关于这个问题已经进行了多次讨论。但我正在寻找一个令人满意的好答案,即以下oops概念。 A.代码重用 B松耦合 C多态性
如果有人能够解释(通过一些使用上述指定技术的示例)何时使用接口以及何时使用抽象类

松耦合意味着封装的组件对彼此的了解刚好足以完成任务-不多也不少。对于系统来说,这是一个很好的特性,因为松散耦合的组件可以更改其实现,而对系统的其他依赖组件几乎没有影响。这提高了系统的可维护性

让我们以迭代器为例。迭代器是允许一个元素一个元素地遍历容器的对象。迭代器可能有多种实现:

  • 列表迭代器
  • 向量迭代器
  • 堆栈迭代器
  • 链表迭代器
  • 队列迭代器
  • 所有实现都因其操作的容器而异。但是迭代器的概念保持不变——它是一种逐元素遍历容器的方法,而不必知道容器实现的细节。可以说迭代器接口是用于遍历容器的抽象

    它是松散耦合的,因为容器实现的细节与元素的遍历方式无关。使用迭代器的客户机不必知道容器是如何实现的,反之亦然

    以下是迭代器接口的示例:

    public interface Iterator { 
         public bool HasNext { get; set;}
         public object Next();
    }
    
    然后可以开发依赖于迭代器抽象的算法。例如,您可以实现反向算法,该算法遍历容器并反转序列:

    public IList<int> Reverse(Iterator iter) {
        var list = new List<int>();
        while (iter.HasNext) {
           list.Insert(0, iter.Next());
        }
        return list;
    }
    
    公共IList反向(迭代器iter){
    var list=新列表();
    while(iter.HasNext){
    Insert(0,iter.Next());
    }
    退货清单;
    }
    
    反向算法的这个实现不知道容器迭代器基于什么(它不在乎)。它可以是堆栈迭代器、向量迭代器等

    您可以通过返回迭代器而不是IList来进一步重构实现:

    public Iterator Reverse(Iterator iter) {
        var list = new List<int>();
        while (iter.HasNext) {
           list.Insert(0, iter.Next());
        }
        return new ListIterator(list);
    }
    
    公共迭代器反向(迭代器iter){
    var list=新列表();
    while(iter.HasNext){
    Insert(0,iter.Next());
    }
    返回新的ListIterator(列表);
    }
    
    那么算法的调用方就不必依赖于IList接口——同样,这里的目标是实现更松散的耦合

    接口vs抽象类vs具体类 这是一个从更抽象到不那么抽象的光谱,或者换句话说,从更松散的耦合到更紧密的耦合

    使用上面的迭代器抽象示例,我们将得到以下范围:

    迭代器基迭代器矢量迭代器

    迭代器是一个接口,它是最抽象的接口,公开的实现细节最少,因此它与使用它的类的耦合最少

    基本迭代器是一个抽象类-它有一个部分实现,实现类将提供其余的实现,使用它的类依赖于抽象类(或部分实现)

    Vectoriator是一个具体的类,它有一个完整的实现。使用它的类依赖于具体的实现,因此与使用它的类有更紧密的耦合

    现实世界类比 这是一个类比。假设你是一名雇员,准备向雇主要求加薪。这已经不是第一次有员工向经理要求加薪了——之前无数其他人已经多次这样做了。假设有一个要求加薪(不乞求)的一般策略,可以最大限度地提高你的成功机会。如果你知道这个策略,那么你可以将它应用到任何一位在你整个职业生涯中取得合理成功的经理身上。这是一个松散耦合设计的示例。员工(任何员工)为了要求加薪而与经理(任何经理)互动。你可以把A经理换成B经理,你成功的机会仍然高于平均水平

    现在,考虑到谣言说他会让他更讨人喜欢,雇员们不知道一般的策略,而是碰巧知道一个对你现任老板(John A. Smith先生)有用的具体策略。这是紧密耦合设计的一个示例。员工(琼斯先生)与特定经理(史密斯先生)互动以要求加薪。你不能把A经理换成B经理,而期望你的成功机会是一样的,因为你的战略很可能只适用于史密斯先生


    就可重用性而言,第一种策略比第二种策略更具可重用性。知道为什么吗

    您似乎只使用了接口,但如何处理代码重用接口、抽象类和具体类都是编码结构。您可以讨论抽象和松耦合,而不必专门讨论代码。不同之处在于一个类可以继承多个接口(加上最多一个类,抽象或非抽象)。由于Java不允许类的多重继承,“接口”绕过了这个限制。其他语言(如C++)具有类的多重继承,因此不需要单独的“接口”概念。