Реализация интерфейса и наследование в C # - PullRequest
1 голос
/ 21 октября 2010

У меня есть код для реализации интерфейса на 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 ]

2 голосов
/ 21 октября 2010

Вам нужно перезаписать метод класса 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 голос
/ 21 октября 2010

Не используйте методы 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



}
0 голосов
/ 21 октября 2010

Когда вы добавили модификатор override к унаследованному виртуальному методу xyz в mc, вы просто отвергли унаследованный виртуальный метод в экземпляре, указанном в mc. Это как если бы вы стерли Base.xyz и записали Derived.xyz на его место в памяти экземпляра mc. Таким образом, экземпляр, на который ссылается mc, не имеет записи о виртуальном xyz в своей реализации и, следовательно, не имеет возможности добраться до него через ссылку mc. Единственный способ получить доступ к виртуальному методу базы - через экземпляр базы, как показано ниже:

 var b = new BaseClass();    
 b.xyz();//  instead of ((BaseClass)mc).xyz()
0 голосов
/ 21 октября 2010

Вы скучаете по пониманию поведения наследования.

Когда вы создаете объект данного типа, который переопределяет некоторый виртуальный метод, вы всегда получите результат от этого метода переопределения. Приведение не меняет структуру объекта, после создания объекта может изменить его состояние после операции приведения.

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.

Ссылки:

Что такое переопределение?

Модификатор, новый в сигнатуре метода

Какой новый модификатор?

0 голосов
/ 21 октября 2010

Вам понадобится var b = new BaseClass(). Тогда b.xyz() вместо ((BaseClass)mc).xyz().

0 голосов
/ 21 октября 2010

Вы не можете сделать это, mc имеет тип Derived, и он всегда будет вызывать xyz в этом классе.Это как наследование работает.Вам нужен экземпляр BaseClass:

var bc = new BaseClass();
bc.xyz(); // In Base Class
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...