【问题标题】:Do we really need interfaces for multiple inheritance in c#?我们真的需要 C# 中的多重继承接口吗?
【发布时间】:2018-03-10 11:59:13
【问题描述】:

在学习接口时,我发现它们可用于实现多接口继承,而多类继承在 C# 中是不可能的。于是,我找到了以下实现多接口继承的代码。

using System;

namespace Test
{
    interface IB
    {
        void PrintB();
    }

    class A
    {
        public void PrintA()
        {
            Console.WriteLine("PrintA() Method.");
        }
    }

    class B : IB
    {
        public void PrintB()
        {
            Console.WriteLine("PrintB() Method.");
        }
    }

    class C : A, IB
    {
        B bObject = new B();

        public void PrintB()
        {
            bObject.PrintB();
        }
    }

    class Program
    {
        public static void Main()
        {
            C cObject = new C();
            cObject.PrintA();
            cObject.PrintB();
        }
    }
}

但是在这段代码中,我们直接继承了 A 类。但是为了继承 Class B 的方法,我们使用了接口 IB。

现在,我看不出这样做的好处。我们可以不用像这样使用接口 IB 来编写这段代码。

using System;

namespace Test
{
    class A
    {
        public void PrintA()
        {
            Console.WriteLine("PrintA() Method.");
        }
    }

    class B
    {
        public void PrintB()
        {
            Console.WriteLine("PrintB() Method.");
        }
    }

    class C : A
    {
        B bObject = new B();

        public void PrintB()
        {
            bObject.PrintB();
        }
    }

    class Program
    {
        public static void Main()
        {
            C cObject = new C();
            cObject.PrintA();
            cObject.PrintB();
        }
    }
}

现在,如果我们可以在没有接口的情况下编写它,为什么我们首先要使用接口?

这是否意味着可以在不使用接口的情况下完成多重继承?

或者即使使用接口也无法进行多重继承?

【问题讨论】:

  • 您提出的替代方案不是一回事。 C 本身不再实现任何其他类型。它包含其他类型的属性。那你到底在问什么?当您个人不想使用接口时,为什么还要存在接口?您编写了一个没有任何意义的人为示例,并将其替换为另一个没有任何意义的人为示例。但这并没有展示任何关于接口的内容。如果你问为什么存在接口,我想有很多关于这个主题的文章。
  • 如果你想在类 C 中使用方法 PrintB 而没有 B bObject = new B(); 怎么办?
  • @David 如果我的例子错了,你能给我一个多接口继承的简单例子吗?
  • 这就像一盘国际象棋。你可以通过阅读来了解这些棋子是如何移动的,但除非你练习,否则你真的不明白如何使用它们。这不是一个可以以问答形式回答的问题。但了解接口有用性的一种方法是阅读本书Dependency Injection in .NET。当然,这只是使用接口的一种方式,在 DI 出现之前它们就已经很有用了。
  • @Learner:"But I would have to implement both interfaces." 是的,这正是我们正在谈论的。多个接口。 "Then why would I inherit from Interfaces?" 所以你的对象可以是这些类型。你似乎遗漏了一些关于静态类型的东西。仅仅因为您编写的类有一个名为CompareTo() 的方法并不意味着它是IComparable 的一个实例。您不能在需要IComparable 而不实现接口的任何上下文中使用它。编译器并不十分关心方法的名称,它关心的是对象的类型。

标签: c# .net multiple-inheritance


【解决方案1】:

您错过了关于虚拟方法的一点。我们希望能够做到这一点:

interface IPrint
{
    void Print();
}

class A : IPrint
{
    public void Print()
    {
    }
}

class B : IPrint
{
    public void Print()
    {
    }
}
...
foreach (IPrint p in printables)
{
    p.Print();
}

您的方法无法做到这一点,因为 C 类中的 PrintB 只是一种方法。继承不是关于具有相同名称的方法,而是关于定义对它们所设计的类的实例执行操作的动词。

【讨论】:

  • 同样的事情可以通过定义一个 A 和 B 都继承的打印类来完成
【解决方案2】:

多重继承导致Diamond Problem。而那颗钻石是程序员最大的敌人。

所以.NET 或 CLI 的设计者(我记不得了)决定他们不打算处理这个问题,并强制要求“仅单一继承”。 Wich是应对“死亡钻石”的常用策略之一。

由于只允许单个继承意味着某些东西会丢失,因此他们实现了接口来抵消它。它是 .NET 中的众多方式之一,比说 Native C++ 更严格,并且不得不发明一个替代品来代替一些琐碎的东西。但从长远来看,事实证明这样做会稍微好一些。

【讨论】:

  • 我认为您的意思是 CLR,而不是 CLI。
  • 我刚刚又查了一遍,CLR 是 CLI 的 .NET 实现的一部分。所以老实说,我不确定这里的限制是否也适用。我确实记得整个事情的某些部分确实支持多重继承。但是开发链上的某个人决定只是避开钻石问题,现在我们陷入了单一继承。
猜你喜欢
  • 2013-02-07
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 2012-05-13
  • 2022-08-12
  • 2012-08-02
  • 1970-01-01
相关资源
最近更新 更多