Заставить метод из базы вызывать новый метод подкласса - PullRequest
0 голосов
/ 05 мая 2018

Насколько я понимаю, подкласс ведет себя точно так же, как родительский класс, за исключением дополнительных методов или методов, которые "переписываются" с помощью ключевых слов new и override. Видимо, это не правильно.

См. Код ниже (скобки сняты для удобства чтения)

class BIG
    protected void Output(string text = "")
        Console.WriteLine("BIG - " + text);

    public void CallingOutput()
        Output("Outputting...");

class SMALL:BIG
    public new void Output(string text = "")
        Console.WriteLine("SMALL - " + text);

class Program
    static void Main(string[] args)
        SMALL foo = new SMALL();

Я уже знаю, что могу скрыть BIG.Output(string) в SMALL с ключевым словом new. При прямом звонке работает отлично.

>> foo.Output("Outputting...")
SMALL - Outputting...

Вот где это противоречит моему пониманию. Я думал, что определение class SMALL:BIG было точно таким же, как если бы я определил class SMALL и скопировал и вставил весь метод из BIG. Короче, я думал, что МАЛЕНЬКИЙ класс выше был эквивалентен этому:

class SMALL
    public void Output(string text = "")
        Console.WriteLine("SMALL - " + text);

    public void CallingOutput()
        Output("Outputting...");

Видимо, это не правильно, потому что

>> foo.CallingOutput()
BIG - Outputting...

Он по-прежнему использует оригинальный Output(string) из BIG при косвенном вызове.

Как правильно сделать так, чтобы foo.CallingOutput() вывел

"SMALL - Outputting..."

Предполагается, что у меня нет доступа к BIG и я не могу вносить изменения. И я не хочу скрывать CallingOutput() также потому, что это в основном переписывает класс. (Да, скрытие CallingOutput() делает это работает)

Я провел поиск, прежде чем опубликовать это, и нашел похожий вопрос в C++. Однако ответить на этот вопрос невозможно.

  1. Я не верю этому. Такой мощный язык, и все же, нет никакого способа сообщить компилятору, какой метод какой.
  2. Это другой язык, поэтому этот пост разрешен, поскольку его нельзя считать дублированием.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Создать шим

Вы не можете ничего изменить или переопределить в существующем классе, если он не предназначен для переопределения. Это по замыслу.

При этом вы можете создать новый класс "shim" (сквозной), который будет точно таким же, как и исходный класс, но с членом, объявленным виртуальным Это достигается с помощью модификаторов new и virtual.

Если у вас есть класс shim, вы можете переопределить метод в обычном порядке. Пример:

class Big
{
    public void Output(string text) { Console.WriteLine("Big - {0}", text); }

    public void CallingOutput()
    {
        Output("Outputting...");
    }
}

class Shim : Big
{
    public new virtual void Output(string text) { base.Output(text); }

    public void CallingOutput()
    {
        Output("Outputting...");
    }
}

Теперь у вас есть класс Shim, который позволит вам то, что вы хотите. Так что создайте подкласс (вместо Big) и посмотрите, что произойдет:

class Small : Shim
{
    public override void Output(string text) { Console.WriteLine("Small - {0}", text); }
}

Проверьте это:

Shim s = new Shim();
s.CallingOutput();   //Original behavior

Shim s = new Small();
s.CallingOutput();   //Overridden behavior

Выход:

Big - Outputting...
Small - Outputting...

Пример для DotNetFiddle

0 голосов
/ 05 мая 2018

заменить ключевые слова new на override следующим образом:

class SMALL:BIG
public override void Output(string text = "")
    Console.WriteLine("SMALL - " + text);
...