简体   繁体   中英

Interface implementation and inheritance in C#

I have some code to implement interface in 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();

    }

I need the console output as provided in comments in Main() . Actual results are

In Derived Class
In Derived Class
In Derived Class

How can I achieve the desired results.

You need to overwrite the method on the Derived class instead of using the virtual / override operators use the new operator.

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

try

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();

}

Don't use virtual methods with the override modifier, but reimplement the interface on the Derived class.

The code below exhibits the required behaviour, but I'd consider this approach slightly confusing and opaque to end users.

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



}

You can't do this, mc is of type Derived and it will always call the xyz in this class. It's how inheritance works. You need an instance of BaseClass:

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

You will need a var b = new BaseClass() . Then b.xyz() instead of ((BaseClass)mc).xyz() .

You are miss understanding the behavior of inherit.

When You create a object of given type that override some virtual method You will alway get result from that override method. The casting do not change the object structure, once create object can change his state after cast operation.

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

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

        Console.ReadKey();

    }

This will product the

In Base Class
In Derived Class

But because there is always a but.

If You overwrite that method You will get the result what You are up to, to overwrite method just use the operator 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");
    }
}

This will use new implementation for DeriveClass and old one for BaseClass.

Links:

What override is ?

Modifier new in method signature

What modifier new is ?

When you added the modifier override to the inherited virtual method xyz in mc , you simply overrode the the inherited virtual method in the instance referred to by mc. Its as if you erased the Base.xyz and written Derived.xyz in its place in memory of the mc instance. So the instance referred to by mc has no record of the virtual xyz in its implementation and therefore no way of getting to it through the mc referrence. The only way to access the base's virtual method is through an instance of the base as demonstrated below:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM