我定义了一个基接口IDrivingLicenceB,IDrivingLicenceA 继承自IDrivingLicenceB,两个接口都有GetLicence方法
然后定义一个基类A里面有个虚方法,B类继承A类,重写a方法。
问题来了,MAIN函数里都是用父类去实例化子类,父接口去实例化子实例。虚方法可以理解,override 了,调用的是子类的方法。但为什么接口明明是NEW,调用的却也是子类的GetLicence呢?????!!
using System;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
    class Program
    {
        class A
        {
            public virtual void a()
            {
                Console.WriteLine("A.a");
            }
        }
        class B : A
        {
            public override void a()
            {
                Console.WriteLine("B.a");
            }
        }
        interface IDrivingLicenceB
        {
           void GetLicence();
        }
        interface IDrivingLicenceA : IDrivingLicenceB
        {
            new void GetLicence();
        }
        class Teacher : IDrivingLicenceA
        {
            public void GetLicence()
            {
                Console.WriteLine("老师获得了A类驾驶执照");
            }
        }
        class Stuednt : IDrivingLicenceB
        {
            public void GetLicence()
            {
                Console.WriteLine("老师获得了B类驾驶执照");
            }
        }
        class Test
        {
            static void DriveCar(string name, IDrivingLicenceB o)
            {
                IDrivingLicenceB dl = o as IDrivingLicenceB;
                if (dl != null)
                {
                    Console.WriteLine(name + "开动了卡车");
                }
                else
                {
                    Console.WriteLine(name + "没有驾驶执照,不能开卡车");
                }
            }
            static void DriveBus(string name, IDrivingLicenceB o)
            {
                IDrivingLicenceA dl = o as IDrivingLicenceA;
                if (dl != null)
                {
                    Console.WriteLine(name + "开动了公交车");
                }
                else
                {
                    Console.WriteLine(name + "没有驾驶执照,不能开公交车");
                }
            }
            static void Main(string[] args)
            {
                Teacher t = new Teacher();
                Stuednt s = new Stuednt();
                A a1 = new B();
                a1.a();
                IDrivingLicenceB ib = t;
                ib.GetLicence();
            }
        }
    }
}

解决方案 »

  1.   

    "问题来了,MAIN函数里都是用父类去实例化子类,父接口去实例化子实例。虚方法可以理解,override 了,调用的是子类的方法"这个理解了,理解接口的就容易了,你可以用下反射工具看看,接口也是一种特殊类,里面的方法都是虚方法。
    前面的关键字是 public   abstract  virtual。
      

  2.   

    那既然NEW隐藏了基类成员class A
            {
                public virtual  void a()
                {
                    Console.WriteLine("A.a");
                }
            }
            class B : A
            {
                public new  void a()
                {
                    Console.WriteLine("B.a");
                }
            }
    static void Main(string[] args)
                {
                    A a1 = new B();
                    a1.a();
                    IDrivingLicenceA ib =t;
                    ib.GetLicence();
                }
    把B转化成A ,A的A1方法调用的还是A(父类)里的方法,因为B里的方法是NEW
            那问题是下面这个接口IB也是父接口实例出子对象。调用的却是子类的方法,是怎么回事啊
      

  3.   

    不管是IDrivingLicenceA还是IDrivingLicenceB,都是同一个方法实现的啊,有什么不能理解的吗?
    首先new的意思就是定义一个有相同名称的不同方法、属性、字段等,并不是替换基类方法,也不是隐藏。
    而类在实现接口的时候,如果没有显示实现接口的方法,那么会自动匹配类中的方法。也就是说Teacher中的GetLicence()方法同时匹配了IDrivingLicenceA,IDrivingLicenceB中的GetLicence()方法。如果你要为IDrivingLicenceB的GetLicence()方法提供不同的实现,那么可以显示实现IDrivingLicenceB接口:void IDrivingLicenceB.GetLicence()
                {
                    Console.WriteLine("老师获得了B类驾驶执照");
                }
      

  4.   

    你调用的确实是IDrivingLicenceB的GetLicence()方法,但是这方法的实现和IDrivingLicenceA.GeLicence()是同一个啊,也就是Teacher中的GetLicence(),结果当然还是一样。
      

  5.   

    那为什么虚方法 在他的子类里用NEW定义一个和他重名的方法时,把子类转化成父类的时候。调用这个对象,实现的却是父类的方法。而接口定义NEW关键字。实现的还是子类的方法
      

  6.   

    还有就是接口的new关键字 跟 虚方法的override关键字一点联系都没有。
    看到的只不过是一个现象而已。
      

  7.   


    IDrivingLicenceA的GetLicence和IDrivingLicenceB的GetLicence是两个不同的方法,而你在定义Teacher的GetLicence方法时,同时实现了这2个接口的GetLicence方法。那么不管你调用IDrivingLicenceA还是IDrivingLicenceB的GetLicence,实际上都是Teacher的GetLicence。
    或者,你认为应该得到什么结果?
      

  8.   

    你可以想下,如果IDrivingLicenceA不继承IDrivingLicenceBinterface IDrivingLicenceB
            {
               void GetLicence();
            }
            interface IDrivingLicenceA 
            {
                void GetLicence();
            }
            class Teacher : IDrivingLicenceA,IDrivingLicenceB
            {
                public void GetLicence()
                {
                    Console.WriteLine("老师获得了A类驾驶执照");
                }
            }虽然IDrivingLicenceA和IDrivingLicenceB的GetLicence()方法一点关系都没有,但实际上在Teacher里还是同一个实现。
      

  9.   


    我明白了点,可是为什么抽象类继承抽象类同名方法只能override,接口只能NEW
      

  10.   

    我看啊,你还是看看C#入门经典里关于“如何隐藏基接口的成员”吧。隐藏基接口的成员用new关键字,其执行方式与隐藏继承类的成员是一样一样的。