Вызов метода дочернего класса из родительского - PullRequest
13 голосов
/ 30 января 2012

Возможно ли, чтобы метод a.doStuff () печатал "B did вещи" без редактирования класса A?Если так, то как бы я это сделал?

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();

        a.doStuff();
        b.doStuff();

        Console.ReadLine();
    }
}

class A
{
    public void doStuff()
    {
        Console.WriteLine("A did stuff");
    }
}

class B : A
{
    public void doStuff()
    {
        Console.WriteLine("B did stuff");
    }
}

Я модерирую паровую игру, Террария.И я не хочу декомпилировать и перекомпилировать все это, потому что это обернется паром.Моя программа «внедряется» в Terraria через XNA.Я могу использовать методы update () и draw () из XNA, чтобы изменить некоторые вещи.Но это довольно ограничено.Я не хочу переопределять базовые методы, чтобы модить больше вещей (например, worldgen).

Ответы [ 3 ]

17 голосов
/ 30 января 2012

Да, если вы объявите doStuff как virtual в A, а затем override в B.

class A
{
    public virtual void doStuff()
    {
        Console.WriteLine("A did stuff");
    }
}

class B : A
{
    public override void doStuff()
    {
        Console.WriteLine("B did stuff");
    }
}
2 голосов
/ 30 января 2012

Поскольку B фактически является наследованием A, а метод перегружен.

A a = new B();
a.doStuff();
0 голосов
/ 30 января 2012

Код для класса A & B, который вы опубликовали, в любом случае сгенерирует приведенное ниже предупреждение компилятора и попросит использовать ключевое слово new в классе B, хотя он будет компилироваться: Ключевое слово new обязательно для 'B.doStuff ()', поскольку оно скрывает унаследованный член 'A.doStuff ()'

Используйте method hiding вместе с ключевыми словами new и virtual в классе Mapper и классе B следующим образом:

class Program
{
    static void Main(string[] args)
    {
        Mapper a = new B(); //notice this line
        B b = new B();

        a.doStuff();
        b.doStuff();

        Console.ReadLine();
    }
}

class A
{
    public void doStuff()
    {
        Console.WriteLine("A did stuff");
    }
}

class Mapper : A
{
    new public virtual void doStuff() //notice the new and virtual keywords here which will all to hide or override the base class implementation
    {
        Console.WriteLine("Mapper did stuff");
    }
}

class B : Mapper
{
    public override void doStuff()
    {
        Console.WriteLine("B did stuff");
    }
}
...