Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.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
C# 为什么Java或C中不允许多重继承?_C#_Java_Language Design_Multiple Inheritance - Fatal编程技术网

C# 为什么Java或C中不允许多重继承?

C# 为什么Java或C中不允许多重继承?,c#,java,language-design,multiple-inheritance,C#,Java,Language Design,Multiple Inheritance,我知道Java和C中不允许多重继承。很多书只是说,多重继承是不允许的。但它可以通过使用接口来实现。没有讨论为什么不允许这样做。有人能确切地告诉我为什么不允许使用MI吗?人们避开MI的主要(尽管不是唯一)原因是所谓的“钻石问题”,导致您的实现不明确。这篇文章对它进行了讨论,并比我所能解释的更好。MI还可能导致更复杂的代码,许多OO设计师声称您不需要MI,如果您使用它,您的模型可能是错误的。我不确定我是否同意最后一点,但保持简单始终是一个好计划。实现的多重继承是不允许的 问题是,如果您有一个Cowb

我知道Java和C中不允许多重继承。很多书只是说,多重继承是不允许的。但它可以通过使用接口来实现。没有讨论为什么不允许这样做。有人能确切地告诉我为什么不允许使用MI吗?

人们避开MI的主要(尽管不是唯一)原因是所谓的“钻石问题”,导致您的实现不明确。这篇文章对它进行了讨论,并比我所能解释的更好。MI还可能导致更复杂的代码,许多OO设计师声称您不需要MI,如果您使用它,您的模型可能是错误的。我不确定我是否同意最后一点,但保持简单始终是一个好计划。

实现的多重继承是不允许的

问题是,如果您有一个Cowboy和一个Artist类,这两个类都有draw()方法的实现,然后您尝试创建一个新的CowboyArtist类型,编译器/运行时无法确定该怎么办。调用draw()方法时会发生什么?是有人死在街上,还是你有一幅可爱的水彩画


我相信这就是所谓的双钻石继承问题。

简单的回答是:因为语言设计者决定不这样做

基本上,.NET和Java设计人员似乎都不允许多重继承,因为他们认为添加MI会给语言增加太多的复杂性,而提供的好处太少

为了更有趣和更深入的阅读,在网上有一些关于一些语言设计师访谈的文章。例如,对于.NET,Chris Brumme(在微软的CLR上工作)解释了他们决定不这样做的原因:

  • 不同的语言实际上对MI的使用有不同的期望 作品例如,冲突是如何发生的 已解决和是否存在重复碱基 合并或冗余。在我们可以之前 在CLR中实现MI,我们必须 所有语言的概览,图 找出共同的概念,并作出决定 如何用语言表达它们 语言中立的态度。我们也会 必须决定MI是否属于 CLS以及这将意味着什么 不需要这个概念的语言 (例如,大概是VB.NET)。属于 当然,这是我们的业务 作为公共语言运行库,但我们 我还没来得及为米做这件事 然而

  • MI真正合适的地方的数量实际上相当多 小的在许多情况下,多个 接口继承可以获得作业 改为做。在其他情况下,您可以 能够使用封装和 代表团。如果我们要添加一个 稍微不同的构造,比如 mixins,那真的会更多吗 强大

  • 多重实现继承给系统注入了大量的复杂性 实施这种复杂性 影响铸造、布局、调度, 字段访问、序列化、标识 比较,可验证性, 反射、泛型和可能 很多其他地方

  • 对于Java,您可以阅读:

    省略多个选项的原因 Java语言的继承 大多源于“简单、客观” 目标明确、熟悉。作为一个 简单语言,Java的创建者 想要一种大多数开发人员都喜欢的语言 无需广泛的理解 训练。为此,他们努力 使语言与C++类似 可能的(熟悉的)没有携带 C++不必要的复杂性 (简单)

    在设计师看来,多个 继承会导致更多的问题和问题 困惑比它解决的要多。所以他们剪掉了 语言的多重继承 (就像他们切断了操作员一样 超载)。设计师的广泛关注 C++经验告诉他们 多重继承根本不值得 头痛


    < C++ >多重继承是使用不当时的一大头痛。为了避免这些流行的设计问题,现代语言(java,C#)强制多接口“继承”。

    另一个原因是单一继承使强制转换变得微不足道,不会发出汇编指令(除了检查所需类型的兼容性之外)。如果您有多重继承,那么您需要找出某个父类在子类中的起始位置。因此,性能当然是一种额外福利(虽然不是唯一的)。

    回到旧时代('70年代),当计算机科学更科学,批量生产更少时,程序员有时间考虑好的设计和良好的实施,因此产品(程序)具有高质量(例如TCP/IP设计和实施)。 如今,当每个人都在编程,管理者在截止日期前更改规格时,像Steve Haigh post在维基百科链接中描述的微妙问题很难追踪;因此,“多重继承”受到编译器设计的限制。如果你喜欢它,你仍然可以使用C++…并且拥有你想要的所有自由:)

    我对“Java中不允许多重继承”的说法持保留态度


    当一个“类型”从多个“类型”继承时,就定义了多重继承。接口也可以根据其行为分类为类型。所以Java确实有多重继承。只是它更安全。

    多重继承更安全

    • 难懂
    • 很难调试(例如,如果您将多个框架中的类混合在一起,这些框架的深层方法具有相同的名称,那么可能会产生意想不到的协同效应)
    • 易误用
    • 不是很有用
    • 很难实现,特别是如果您希望正确高效地完成

    因此,不在Java语言中包含多重继承被认为是明智的选择。

    因为Java有着巨大的
       public class A                               
         {
           void display()
             {
               System.out.println("Hello 'A' ");
             }
         }
    
       public class B                               
          {
            void display()
              {
                System.out.println("Hello 'B' ");
              }
          }
    
      public class C extends A, B    // which is not possible in java
        {
          public static void main(String args[])
            {
              C object = new C();
              object.display();  // Here there is confusion,which display() to call, method from A class or B class
            }
        }
    
    interface A
        {
           // display()
        }
    
    
     interface B
        {
          //display()
        }
    
     class C implements A,B
        {
           //main()
           C object = new C();
           (A)object.display();     // call A's display
    
           (B)object.display(); //call B's display
        }
    }
    
    Class Shape1
    {
    
     public void CalculateArea()
    
         {
           //
         }
    }
    
    Class Shape2
    {
    
     public void CalculateArea()
    
         {
    
         }
    }
    
    public class Circle: Shape1, Shape2
    {
    }
    
    class A {
        protected:
        bool flag;
    };
    class B : public A {};
    class C : public A {};
    class D : public B, public C {
        public:
        void setFlag( bool nflag ){
            flag = nflag; // ambiguous
        }
    };
    
    B::flag = nflag;