代码之家  ›  专栏  ›  技术社区  ›  Chandra Mohan

具有与具有新关键字的基类相同接口的子类

  •  2
  • Chandra Mohan  · 技术社区  · 6 年前

    我在试着理解为什么它的行为如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AbstarctWithInterfcae
    {  
    public interface IBase
    {
        void Display();
    }
    
    public abstract class Base : IBase
    {        
        public void Display()
        {
            Console.WriteLine("Base Display");
        }
    }
    
    
    public class child1 : Base, IBase
    {
        public new void Display()
        {
            Console.WriteLine("child1 Display");
        }
    }
    
    public class child2 : Base,IBase
    {     
        public new void Display()
        {
            Console.WriteLine("child2 Display");
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            IBase obj = new child1();
            obj.Display(); // writing child1 display
            IBase obj2 = new child2();
            obj.Display(); //Wrirting child1 dispaly
            Console.ReadLine();
        }
    }
    }
    

    第一个问题:

    在上面的程序中,当我使用new时,它应该调用基类方法 为什么是 调用子1显示 ?

    根据我的理解,我们有一个基类,它已经实现了ibase,所以当我们通过引用接口为child1创建实例时,它应该调用基类方法,因为它包含基类并有新的关键字。

    如果有人能解释一下

    2 回复  |  直到 6 年前
        1
  •  -1
  •   C Bauer    6 年前

    场景1是因为您正在使用 obj.Display() 而不是 obj2.Display()

    场景2是因为您正在使用通用接口引用 IBase , IBase obj = new child2() )而c将选择最不复杂的类型来适应实际对象类型的这种情况,因为它假定您希望对该类型的“最不特定版本”进行操作,因为您不是特定的。

    编辑:注意到投票结果被否决,我假设有人认为这个答案不够完整;

    如果op希望正确地看到错误2的输出,则可以将类型实例化为 Child2 obj = new Child2();

        2
  •  1
  •   Servy    6 年前

    你在这里看到的是接口的重新实现。在第一种情况下,基类是实现接口的最派生类,因此它将接口的方法绑定到它的方法实现。由于该方法不是虚拟的,因此它不能也不会被重写,因此这是在基类或派生类上使用接口时调用的方法。

    在第二个示例中,您在派生类上重新实现接口(通过将其添加到类的声明中)。这将重新绑定接口的方法 使用那种类型 . 因为它有一个合适的方法,所以每当使用接口为派生类型分派方法时,都会使用它的实现。