接口是多余的多重继承?

时间:2010-12-02 15:53:16

标签: oop interface abstract-class language-features multiple-inheritance

关于抽象类和接口之间的区别,这还不是另一个问题,所以在投票结束之前请三思。

我知道接口在那些不支持多重继承的OOP语言中是必不可少的 - 比如C#和Java。但那些带有多重继承的呢?在具有多重继承的语言中,接口(作为特定语言特性)的概念是多余的吗?我猜可以使用抽象类来建立类之间的OOP“契约”。

或者,更明确地说,C#和Java中的接口只是它们不支持多重继承的结果吗?

7 个答案:

答案 0 :(得分:8)

完全没有。接口定义契约而不指定实现。

所以即使存在多重继承也需要它们 - 继承是关于实现的。

从技术上讲,您可以在多继承中使用抽象类来模拟接口。但是因此人们可能倾向于在那里写一些实现,这将产生很大的混乱。

答案 1 :(得分:8)

取决于冗余测试。

如果测试是“可以在没有语言功能的情况下实现此任务”那么类本身就是多余的,因为有图灵竞争语言没有类。或者,从工程基础来看,除了机器代码之外的任何东西都是多余的。

实际上,测试是语法和语义的更微妙的组合。如果它没有改善语言的语法或语义,那么对于合理的用途来说,事情是多余的。

在区分的语言中,支持接口声明类知道如何以某种方式进行交谈。继承自另一个类导入(并且可能扩展或修改)另一个类的功能。

由于这两个任务在逻辑上不相同,我认为接口不是冗余的。区分这两者可以改进大量程序的语义,因为它可以更具体地指示程序员的意图。

答案 2 :(得分:7)

  

......缺乏多重继承   迫使我们添加概念   接口...

所以是的,我相信在多重继承的情况下,接口是多余的。您可以在支持多继承或混合的语言中使用纯抽象基类。

那就是说,我对大部分时间的单身遗产都很满意。 Eric Lippert在同一卷(第10页)中更早地指出单继承的选择“......一次性消除了许多复杂的极端情况......”

答案 3 :(得分:5)

有些语言支持多重继承,不包含Java接口的并行概念。埃菲尔就是其中之一。 Bertrand Meyer没有看到他们的需要,因为有能力定义一个延迟类(这是大多数人称之为抽象类的东西)与一个充实的合同。

缺少多重继承可能导致程序员需要创建实用程序类等以防止在实现相同接口的对象中编写重复代码的情况。

合同的存在可能是对缺乏完全无实现的接口概念的重要贡献......如果没有一些实施细节可以进行测试,合同就更难写。

因此,技术上接口在支持MI的语言中是多余的。

但是,正如其他人所指出的那样......多次继承可能是一个非常棘手的事情,无论如何都要正确使用。我知道我不能......我为Meyer工作,因为他正在起草面向对象的软件构建,第2版。

答案 4 :(得分:4)

  

C#和Java中的接口是否只是一个   他们这样做的结果   不支持多重继承?

是的,他们是。至少在Java中。作为一种简单的语言,Java的创建者想要一种大多数开发人员无需大量培训即可掌握的语言。为此,他们努力使语言尽可能与C ++类似(熟悉),而不会带来C ++不必要的复杂性(简单)。 Java的设计者选择通过使用接口来允许多个接口继承,这是一个借鉴Objective C协议的想法。 See there for details

而且,是的,我相信,如果你有多重继承,就像在C ++接口中一样多余。如果你有一个更强大的功能,为什么要少保留一个?

答案 5 :(得分:2)

好吧,如果你这样做,你可以说C和C ++,C#和其他高级语言是多余的,因为你可以使用程序集编写你想要的任何代码。当然,你没有绝对需要这些高级语言,但是,它们有很多帮助。

所有这些语言都有各种实用程序。对于其中一些,接口概念是这些实用程序之一。所以,是的,在C ++中,你可以避免使用接口和抽象类,而无需实现。

事实上,如果你想用C编程Microsoft COM,虽然C不知道接口概念,你可以这样做,因为所有.h文件都是这样定义接口的:

#if defined(__cplusplus) && !defined(CINTERFACE)
    MIDL_INTERFACE("ABCDE000-0000-0000-0000-000000000000")
    IMyInterface : public IUnknown
    {
   ...
    }
#else   /* C style interface */
    typedef struct IMyInterfaceVtbl
    {
        BEGIN_INTERFACE

        HRESULT ( STDMETHODCALLTYPE *SomMethod )(... ...);

        END_INTERFACE
    } IMyInterfaceVtbl;

    interface IMyInterface
    {
        CONST_VTBL struct IMyInterfaceVtbl *lpVtbl;
    };
#endif

某种另一种语法糖......

并且说在C#中,如果我没有接口概念,我不知道我怎么能真正编码:)。在C#中,我们绝对需要接口。

答案 6 :(得分:1)

接口比多重继承更可取,因为继承根据“Effective Java”第16项Favor composition over inheritance.

违反了封装