2015-10-05 8 views
2
class MyBaseClass 
{ 
    virtual public void Print() 
    { 
     Console.WriteLine("This is the base class."); 
    } 
} 

class MyDerivedClass : MyBaseClass 
{ 
    override public void Print() 
    { 
    Console.WriteLine("This is the derived class."); 
    } 
} 

class Program 
    { 
    static void Main() 
    { 
     MyDerivedClass derived = new MyDerivedClass(); 
     MyBaseClass mybc = (MyBaseClass)derived; 

     derived.Print(); 
     mybc.Print(); 

    } 
    } 

ВЫВОД:производный класс не вызывает метод базового класса

This is the derived class. 
This is the derived class. 

Я не понимаю, почему второй печатает вызов, полученные методом класса для печати(), потому что я бросил mybc объект базового класса. Я ожидаю, что вместо этого он напечатает метод печати базового класса. Я что-то упустил?

+0

Заканчивать подобный задаваемый вопрос на этом сайте для вдумчивого обсуждения: http://stackoverflow.com/questions/1334254/how-can-i-call-the-base-implementation-of-an- overridden-virtual-method –

+0

удалить ключевое слово override, и все будет нормально работать –

+0

@PranavPatel Это будет работать в техническом смысле, но в целом это будет плохой дизайн. –

ответ

4

Тип переменной и тип экземпляра два различных типа. Кастинг не меняет тип экземпляра.

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

Также обратите внимание, что это присвоение действительно - синтаксис заливки не требуется для изменения типа переменной из подкласса в базовый класс. Этот вид приведения может быть сделан неявно.

MyBaseClass mybc = derived; 
+0

Остерегайтесь синтаксиса C# cast, который иногда отличает и иногда преобразует. –

+0

Когда я делаю производный объект в базовый объект, как в приведенном выше коде, я могу изменить тип объекта или нет? Например, в этом фрагменте кода mybc стал объектом MyBaseClass или это просто указатель на производный объект? Выведено MyBaseClass mybc = (MyBaseClass); – Lyrk

+0

У вас нет. Вы говорите: «Используйте эту переменную Shape для обозначения моей площади», но она по-прежнему является квадратом. –

2

Весь смысл переопределения виртуальных методов заключается в том, что вызывается версия для базового (runtime) типа объекта, а не для статического типа (время компиляции), даже если вы вызываете его по типу объявленный как базовый класс.

Так что это ведет себя так, как должно.

Если бы это было не так, это сделало бы большую полезность иерархии классов бесполезной, потому что вы не могли изменить поведение класса, переданного методу, передав ему настроенный производный класс.

3

Вы его переопределили. Он вызывает только производный метод. Вы должны явно call the base class' method:

override public void Print() { 
    base.Print(); 
    Console.WriteLine("This is the derived class."); 
} 
+0

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

Смежные вопросы