C#中的接口实现和继承

时间:2010-10-21 08:19:11

标签: c# inheritance interface

我有一些代码在C#中实现接口

public interface Intfc { void xyz();}

public class BaseClass : Intfc
{

    public virtual void xyz()
    {
        Console.WriteLine("In Base Class");
    }
}

public class Derived : BaseClass
{
    public override void xyz()
    {
        Console.WriteLine("In Derived Class");
    }
}

static void Main(string[] args)
    {
        Derived mc = new Derived();
        mc.xyz(); //In Derived Class
        ((BaseClass)mc).xyz(); //In Base Class
        ((Intfc)mc).xyz(); //In Derived Class

        Console.ReadKey();

    }

我需要Main()中的评论中提供的控制台输出。 实际结果是

In Derived Class
In Derived Class
In Derived Class

如何达到预期效果。

6 个答案:

答案 0 :(得分:2)

您需要覆盖Derived类上的方法,而不是使用虚拟/覆盖运算符使用new运算符。

http://msdn.microsoft.com/en-us/library/51y09td4(VS.71).aspx#vclrfnew_newmodifier

尝试

public interface Intfc { void xyz();}

public class BaseClass : Intfc
{
    public void xyz()
    {
        Console.WriteLine("In Base Class");
    }
}

public class Derived : BaseClass
{
    new public void xyz()
    {
        Console.WriteLine("In Derived Class");
    }
}

static void Main(string[] args)
{
    Derived mc = new Derived();
    mc.xyz(); //In Derived Class
    ((BaseClass)mc).xyz(); //In Base Class
    ((Intfc)mc).xyz(); //In Derived Class

    Console.ReadKey();

}

答案 1 :(得分:1)

不要将virtual方法与override修饰符一起使用,而是重新实现Derived类的接口。

下面的代码展示了所需的行为,但我认为这种方法对最终用户来说有点混乱和不透明。

public interface Intfc { void xyz();}

public class BaseClass : Intfc
{

    public void xyz()
    {
        Console.WriteLine("In Base Class");
    }
}

public class Derived : BaseClass,Intfc
{
    public void xyz()
    {
        Console.WriteLine("In Derived Class");
    }
}

static void Main()
{
    Derived mc = new Derived();
    mc.xyz(); //In Derived Class
    ((BaseClass)mc).xyz(); //In Base Class
    ((Intfc)mc).xyz(); //In Derived Class



}

答案 2 :(得分:0)

您无法执行此操作,mc属于Derived类型,并且始终会在此课程中调用xyz。这是继承的工作原理。您需要一个BaseClass实例:

var bc = new BaseClass();
bc.xyz(); // In Base Class

答案 3 :(得分:0)

您需要var b = new BaseClass()。然后b.xyz()代替((BaseClass)mc).xyz()

答案 4 :(得分:0)

您很难理解继承的行为。

当您创建给定类型的对象覆盖时,某些虚拟方法您将始终从该覆盖方法获得结果。一旦创建对象在转换操作后可以改变其状态,则转换不会改变对象结构。

static void Main(string[] args)
    {
        Intfc mc1 = new Derived();
        Intfc mc2 = new BaseClass();

          mc1.xyz();
          mc2.xyz();

        Console.ReadKey();

    }

这将产生

In Base Class
In Derived Class

但是因为总有一个但是。

如果您覆盖该方法您将获得结果,覆盖方法只需使用运算符 new

public class Derived : BaseClass
{
    new public void xyz()
    {
        Console.WriteLine("In Derived Class");
    }
}

public class BaseClass : Intfc
{

    public void xyz()
    {
        Console.WriteLine("In Base Class");
    }
}

这将使用DeriveClass的新实现和BaseClass的旧实现。

链接:

What override is ?

Modifier new in method signature

What modifier new is ?

答案 5 :(得分:0)

当您将修饰符override添加到mc中继承的虚方法xyz时,您只需覆盖mc引用的实例中的继承虚方法。它好像你擦除了Base.xyz并在mc实例的内存中写了Derived.xyz。因此,mc引用的实例在其实现中没有虚拟xyz的记录,因此无法通过mc引用获取它。访问base的虚方法的唯一方法是通过base的实例,如下所示:

 var b = new BaseClass();    
 b.xyz();//  instead of ((BaseClass)mc).xyz()