有三个接口IA,IB,IC,
每个接口定义了很多函数,IAF1,IAF2...,IBF1,IBF2...,ICF1,ICF2...
三个接口分别由类A,B,C实现,
现在有一个类X需要通过A,B,C同时具备IA,IB,IC的功能
代码如下internal interface IA
{
    void IAF1();    void IAF2();
}internal interface IB
{
    void IBF1();    void IBF2();
}internal interface IC
{
    void ICF1();    void ICF2();
}internal class A : IA
{
    public void IAF1()
    {
    }    public void IAF2()
    {
    }
}internal class B : IB
{
    public void IBF1()
    {
    }    public void IBF2()
    {
    }
}internal class C : IC
{
    public void ICF1()
    {
    }    public void ICF2()
    {
    }
}internal class X : IA, IB, IC
{
    private A a = new A();
    private B b = new B();
    private C c = new C();    public void IAF1()
    {
        a.IAF1();
    }    public void IAF2()
    {
        a.IAF2();
    }    public void IBF1()
    {
        b.IBF1();
    }    public void IBF2()
    {
        b.IBF2();
    }    public void ICF1()
    {
        c.ICF1();
    }    public void ICF2()
    {
        c.ICF2();
    }
}
问题,类X是否只能通过这种类似于"转发"的形式将功能的调用分别转给A,B,C
考虑到实际情况可能除了A,B,C之外可能还有更多类,且每个类提供的也不是一两个功能
X的这种大量的转发工作看起来比较蠢,是否有更优雅的方式呢?

备注:
x是一个功能很多的模块,虽然功能很多,但这些功能都是必要的且与模块的目的高度相关的,
不过好在其功能还是能分类的,所以将其功能分类并抽象为IA,IB,IC,三个接口并分别由类A,B,C实现,
将A,B,C分别提供给使用者是无意义的,因为它们每个单独的功能并不能解决问题,只有将它们整合起来形成一个X再交给使用者才是有意义的
就像一辆车有油门和刹车等功能,作为厂家可以分别实现,但交给驾驶者的是一辆完整的车而不是实现了油门和刹车等功能的零件

解决方案 »

  1.   


    这在设计上是这样的,但是在 c# 实现上是完全不可能的,因为 c#/.net 并不支持多重继承。所以 X 顶多只能继承一个 class,然后实现另外两个接口。不可能继承3个class。对于 java、.net 来说,都是不支持多重继承的。有一些优秀的编程语言是支持多重继承的,可惜并没有流行起来。
      

  2.   


    把多个功能组合为一个对象功能,这中“集中式”是最垃圾的,早期的所谓“DDD”书籍中就是这种很垃圾的模式,所以 DDD 坑人。假设 X 继承自 A、B、C,那么一个 X“就是”A、“就是”B、“就是”C。继承是 Is-A 概念而不是 Has-A 概念。如果 X 组合了 A、B、C 那么应该定义为public class X
    {
        public IA A;
        public IB B;
        public IC C;
        ......
    }这才是组合的概念。如果连组合都不懂,把一个人有儿子说成是“儿子就是自己的爸爸”这就是荒唐可笑乱伦的了,而且随后会产生无限多诡异的程序逻辑。组合和继承,是完全不同的概念。而即使对于“组合”来说,在 DDD 中主张的那种将各种功能组合到一个对外的功能集合中的做法,也是垃圾的、不能很好地体现接口功能。
      

  3.   

    C++ 是支持多重继承的
    不过,若父类们都有同名方法(功能不同)时,子类就会无所适从了。因为无法用规则限定使用那个父类的继承方法
    于是 Java、C# 都放弃了多重继承,而使用接口来曲线救国接口实际是原型声明,告知用户:一定有这些方法可用。并不提供实质性功能
    接口是类与外部沟通的渠道,无论类的内部多么复杂、功能多么不相同,只要实现了相同的接口,我们就可以用相同的方法使用他们由于有了统一的接口,那么从 油门厂购买到的就一定是 油门,从刹车购买到的就一定是刹车,这样就把 采购 这个行为抽象出来了
      

  4.   


    interface IB
        {
            void IBF1();        void IBF2();
        }
        interface IX : IA, IB
        {    }    class X : IX
        {
            void IA.IAF1()
            {
                throw new NotImplementedException();
            }        void IA.IAF2()
            {
                throw new NotImplementedException();
            }        void IB.IBF1()
            {
                throw new NotImplementedException();
            }        void IB.IBF2()
            {
                throw new NotImplementedException();
            }
        }    class Program
        {
            static void Main()
            {
                IA a = new X();
                a.IAF1();
                a.IAF2();
                IB b = new X();
                b.IBF1();
                b.IBF2();
                IX x = new X();
                x.IAF1();
                x.IAF2();
                x.IBF1();
                x.IBF2();
            }
        }
      

  5.   


        interface IA
        {
            void IAF1();        void IAF2();
        }    interface IB
        {
            void IBF1();        void IBF2();
        }
        interface IX : IA, IB
        {    }    class X : IX
        {
            void IA.IAF1()
            {
                throw new NotImplementedException();
            }        void IA.IAF2()
            {
                throw new NotImplementedException();
            }        void IB.IBF1()
            {
                throw new NotImplementedException();
            }        void IB.IBF2()
            {
                throw new NotImplementedException();
            }
        }    class Program
        {
            static void Main()
            {
                IA a = new X();
                a.IAF1();
                a.IAF2();
                IB b = new X();
                b.IBF1();
                b.IBF2();
                IX x = new X();
                x.IAF1();
                x.IAF2();
                x.IBF1();
                x.IBF2();
            }
        }
      

  6.   


    这在设计上是这样的,但是在 c# 实现上是完全不可能的,因为 c#/.net 并不支持多重继承。所以 X 顶多只能继承一个 class,然后实现另外两个接口。不可能继承3个class。对于 java、.net 来说,都是不支持多重继承的。有一些优秀的编程语言是支持多重继承的,可惜并没有流行起来。从头到尾,我提都没提继承的事情.
      

  7.   

    不管嘴上说的什么,言行不一,代码会出卖你,因为代码不说假话,代码比人老实。如下的代码是你写的问题核心吧?internal class X : IA, IB, IC
    {
    你也是用汽车有油门和刹车来说明 IA、IB、IC 吧?只能说,你不知道自己学了什么知识,就直接拿这些术语来用了。
      

  8.   

    四抠字眼儿是缺少理解力的。比如硬要说“我的 X 只是‘实现’接口 IA、IB、IC,我并没有说继承这个字眼儿啊?”这就是搞不懂设计跟编程实现的区别。不同语言有不同的语法、不同的术语,但是在设计上使用接口和继承父类没有什么设计上的区别。这需要先学习设计概念,然后再来反复理解编程语句。而不是本末倒置地以技术字眼儿为核心。