Зачем мне объявлять виртуальный метод, когда я могу скрыть его в производном классе - PullRequest
1 голос
/ 08 ноября 2011
class clsTestParent
    {
       public void testNoAbstract()
        {
            Console.WriteLine("Parent Method Call");
        }
    }

    class clsDerivedTest : clsTestParent
    {
     public void testNoAbstract()
        {
            Console.WriteLine("Child Method Hiding Parent Method");
        }
    }

            clsTestParent objParent = new clsTestParent();
            clsTestParent objOfParentFromDerived = new clsDerivedTest();
            clsDerivedTest objDerived = new clsDerivedTest();

            objParent.testNoAbstract();
            objOfParentFromDerived.testNoAbstract();
            objDerived.testNoAbstract();

Вывод:
Вызов родительского метода
Вызов родительского метода
Скрытие дочернего метода Родительский метод

Но когда я объявляю testNoAbstract() виртуальным иЕсли перебрать в производном классе, то выход будет таким, как показано ниже:

Parent Method Call  
Child Method Hiding Parent Method
Child Method Hiding Parent Method

Раньше я думал, что мы можем переопределить метод только в производном классе, если он определен как abstract или virtual, но, как видно сейчас, мы можем скрыть метод родительского класса, просто переопределив его в производном классе.

Хотя, как я вижу, разницу в выводе путем изменения кода я хотел бы знатьКаковы различия между двумя вышеупомянутыми методами и почему они дают разный результат?

Ответы [ 2 ]

3 голосов
/ 08 ноября 2011

Если вы когда-либо сделаете clsTestParent a = new clsDerivedTest () - вы никогда не сможете выполнить его в классе clsDerivedTest !!!!

В этом разница и поэтому компилятор предупреждает вас.

вы на самом деле это сделаете, если захотите предварительно сформировать архитектуру Полиморфизма.

Microsoft говорит вам : «слушайте, вы направили класс, и мы дадим вам все публичные вещи и т. Д., Но мы не знаем, как вы хотите реализовать методы ... если вы будете используйте виртуальный + переопределение - вы сможете выполнить другой метод через тип instace. и если вы не переопределите - так всегда будет выполняться функция отца ... ваш выбор ... мы предупреждаем вас " ... и они предупреждают

2 голосов
/ 08 ноября 2011

Вот почему «переопределение» является несколько плохим словом для этого.Виртуальный вызов разрешает ваш тип времени выполнения, поэтому вы смогли:

    clsTestParent objOfParentFromDerived = new clsDerivedTest();
    objOfParentFromDerived.testAbstractOrVirtual(); // marked as virtual or abstract in base class

, и вызов был разрешен во время выполнения, к методу, определенному в классе, который действительно objOfParentFromDerived (оператор new -clsDerivedTest), а не к методу, определенному в классе, с которым он был объявлен (clsTestParent).

Если он не отмечен ни virtual, ни abstract, то компилятор предупреждает вас, потому чтовызов будет решен на основе типа, с которым была объявлена ​​переменная.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...