zoukankan      html  css  js  c++  java
  • 天轰穿C# vs2010 04面向对象的编程之多重继承 【原创】

    小天:接口主要是给类做父类的吗?它还能不能继承其它的接口呢?

           老田:当然是可以的,不过接口继承接口会有一个问题。通过前面的介绍也知道了,接口本身是不会去实现任何方法的。它只是规定了要实现那些方法,以及要什么样的材料(参数),能够生产什么样的产品(返回值)。于是,接口继承接口的结果就是越往后的接口所带的成员就越多了。例如,下面代码,

        interface I_2_A     //声明第一个接口

        {

            int A { get; set; }   //声明一个属性

        }

        interface I_2_B     //声明第二个接口

        {

            int Count(int i, int j); //声明一个方法

        }

        interface I_2_C : I_2_A, I_2_B

        {//声明第三个接口又继承了前两个接口

        } 

        //什么都没有声明。但是他实际上是继承了前面两个接口的属性和方法。

        public class I_2_L : I_2_C  //声明一个类,他继承了I_2_C这个接口

        {

            int a;

            public int A

            {

                get { return a; }

                set { a = value; }

            }

            public int Count(int i, int j)

            {

                return i * j * a;

            }

    }

        class Program

        {

            //----------------------使用接口----------------------------------

            static void Main(string[] args)

            {

                //接口第二个实例,I_2_A、I_2_B、I_2_C、I_2_L 的实例

                //使用I_2_A,只有一个属性A

                I_2_A i2a = new I_2_L();

                Console.WriteLine(i2a.A);

                //使用I_2_B,只有一个Count方法

                I_2_B i2b = new I_2_L();

                Console.WriteLine(i2b.Count(2,5));

                //使用I_2_C,既有方法也有属性

                I_2_C i2c = new I_2_L();

                Console.WriteLine("i2c.A={0},i2c.Count(3,15)={1}", i2c.A, i2c.Count(3, 15));

     

                Console.ReadLine();

            }

     }

           上面一共申明了三个接口,分别是I_2_A中有一个A属性, I_2_B中有一个Count方法,接着就申明了I_2_C这个接口来继承前面两个接口。虽然这第三个接口中啥都没有,但是这一继承就有了一个属性和一个方法。于是I_2_L这个类来继承I_2_C这个接口,这便需要实现所有I_2_C这个接口所背负的责任。

           打个很不恰当的比方,两个非常有大志的夫妻被困荒岛,他们不小心生了一个孩子,终于有一天,有人来就他们了。可惜这对夫妻已经很老了,无法离开这里。于是他们就将他们两的理想都加到孩子身上,希望得到实现。

           另外,从上面看应该看出一点,接口可以多重继承,而多个接口之间则是用逗号分隔。语法如下:

    类或接口 : 接口1,接口2,接口N      //这是纯继承接口

    类 : 类,接口1,接口2,接口N        //类始终只能继承一个,但是可以混合继承

           小天:既然可以多重继承,那么会不会出现成员重复的情况?比如接口1和接口2中某两个方法重复,这种情况下继承该怎么办?而使用的时候又怎么办?

           老田:这个问题问得太好了,先看下面的实例:

        public interface I_3_A

        {

            int Count { get; set; }

            int J(int j);

        }

        public interface I_3_B

        {

            void Count(int i);

            double J(double j);

        }

        public interface I_3_C : I_3_A, I_3_B

        { }

        //---------------------使用上面的接口--------------------

        public class I_3_L

        {

            public void Sum(I_3_C thc)

            {

                thc.Count();  //错误,具有二义性

                thc.Count = 1;  //错误,具有二义性

                thc.Count(1);   //错误,具有二义性,其实相对来说,这个也可以说不具备二义性

     

                ((I_3_A)thc).Count = 1;     //正确,最好是这样明确一点,也增加代码的易读性

                ((I_3_B)thc).Count(1);

     

                ((I_3_A)thc).J(1);

                ((I_3_B)thc).J(1);

                thc.J(1.0);

                thc.J(1);

            }

        }

    从上面实例看得出来,外部对接口的访问,如果出现同名的参数或者方法,必须显示的指出他的父接口。特别是在不清楚具体情况的前提下,最好是做得保守一点。

           小天:如果用一个抽象类来继承接口会是什么效果?

           老田:一回事。上面不是说了,就算是抽象类来继承接口,那么也必须将接口的方法给实现了吗?就算自己不实现,那也必须让方法可以传递下去,被下面的派生来再来实现。如图4-32

     

                         图4-32

    根据上面的类关系图写出代码,然后可以对照下面:

        public interface I_4_A

        {

            int J(int j);

        }

        public interface I_4_B

        {

            int Count(int i);

        }

        //申明抽象类,继承I_4_A

        public abstract class I_4_L : I_4_A

        {

            //将方法申明为抽象方法,这样就表示等待被下面的方法来扩展

            public abstract int J(int j);

        }

        //申明一个普通类,用来继承I_4_L抽像类和I_4_B接口

        public class I_4_M : I_4_L, I_4_B

        {

            //实现抽象类的方法,其实这个方法,是I_4_A接口规定了的,不过被I_4_L给移交过来了

            public int Count(int i)

            {

                return i*10;

            }

            //实现接口中的方法

            public override int J(int j)

            {

                return j * 20;

            }

    }

    //----------------------使用接口----------------------------------

        class Program

        {

            static void Main(string[] args)

            {

                I_4_L i4l = new I_4_M();    //实例化一个抽象类型I_4_L类型的对象

                Console.WriteLine(i4l.J(10));

                I_4_B i4b = new I_4_M();    //实例化接口I_4_B类型的对象

                Console.WriteLine(i4b.Count(10));

               

                Console.ReadLine();

            }

     }

           小天:我刚才在VS中练习的时候,看到在被继承的接口下面出现了个绛紫色的小框,一点,居然提示上面显示实现接口和实现接口,这个是什么意思?如图4-33

     

                         图4-33

           老田:这个很简单了,你都点击看看效果就知道了,如下

        public class I_4_M : I_4_L, I_4_B

        {

            //实现 I_4_B 成员

            public int Count(int i)

            {

                //。。。。。。。。。。。

            }

            //显示实现 I_4_B 成员

            int I_4_B.Count(int i)

            {

                //。。。。。。。。。。。

            }

        }

           有什么区别?

           这个主要用于,万一某个派生类继承的多个接口中有同样的方法这种情况,这就会导多个父接口打架了,都认为孩子是自己的。所以只好用显示实现了,这样也就不会误会了。

     本文章为天轰穿原创作品,转载请注明出处及作者。

  • 相关阅读:
    离线安装SilverLight
    Singleton模式
    首次进入
    实现多层菜单(=_=!)(很傻又很土的办法)
    【转】Java中Split函数的用法技巧
    【转】来电显示
    DatePickerDialog
    Unable to resolve target 'android9'
    退出activity的另一种写法
    滚轮控件的定义和使用
  • 原文地址:https://www.cnblogs.com/thcjp/p/2891686.html
Copyright © 2011-2022 走看看