#c# #oop
#c# #ооп
Вопрос:
У меня есть следующий код. Кто-нибудь может ответить, почему вызывается метод base-show, а не метод derive-show в этом случае. Как в этом случае будет выделяться память для функций show производного и базового классов.
class OverrideAndNew : Derive
{
public static void Main()
{
Derive obj = new Derive1();
obj.Show();
Console.ReadLine();
}
}
class Base
{
public virtual void Show()
{
Console.WriteLine("Base - Show");
}
}
class Derive : Base
{
protected virtual void Show()
{
Console.WriteLine("Derive - Show");
}
}
class Derive1 : Derive
{
protected override void Show()
{
Console.WriteLine("Derive1 - Show");
}
}
Ответ №1:
Потому что вы ее вызвали. Вы не можете изменять модификаторы доступа при переопределении метода. Итак, по сути, Derive1 переопределил Show метод Derive . Но функция derive никогда не переопределяла функцию Base. Итак, существует только один общедоступный метод Show, реализованный в Base.
То, что вы, вероятно, хотели сделать, было:
class OverrideAndNew
{
public static void Main()
{
Derive obj = new Derive1();
obj.Show();
Console.ReadLine();
}
}
class Base
{
public virtual void Show()
{
Console.WriteLine("Base - Show");
}
}
class Derive : Base
{
public override void Show()
{
Console.WriteLine("Derive - Show");
}
}
class Derive1 : Derive
{
public override void Show()
{
Console.WriteLine("Derive1 - Show");
}
}
Обратите внимание, что сигнатура метода остается неизменной. Она всегда общедоступна, потому что Base сказал, что она должна быть общедоступной. Это всегда одно и то же имя, возвращаемый тип и параметры (в данном случае их нет).
Комментарии:
1. Просто чтобы добавить к ответу nvoigt из документации MSDN по защищенному модификатору «Защищенное ключевое слово является модификатором доступа участника. Защищенный элемент доступен внутри своего класса и экземплярами производного класса.». Следовательно, вызывая метод объекта, вы получаете доступ к общедоступному методу (т.Е. Base).
Ответ №2:
Ваш защищенный метод не переопределяет Base.Show
, он просто скрывает его. Вам нужно объявить Show
в Derive
с тем же модификатором доступа (т. Е. public) и использовать override
ключевое слово, чтобы явно объявить, что вы намерены переопределить метод.
Обратите внимание, что эта программа выдает предупреждение компилятора, в котором говорится следующее:
‘Производная.Show()’ скрывает унаследованный элемент ‘Base.Show()’. Чтобы заставить текущий элемент переопределять эту реализацию, добавьте ключевое слово override. В противном случае добавьте ключевое слово new.
Отдельный вопрос заключается в том, почему это всего лишь предупреждение, а не ошибка. Это потому, что C # разработан для минимизации так называемой проблемы хрупкости базового класса. Если Base
она находится в одной сборке, а Derive
— в другой (возможно, созданной разными командами или даже разными компаниями), то с точки зрения автора Derive
было бы нежелательно, если бы версия 2 Base
добавила новый метод Show
, который нарушил существующий код в Derive
. Следовательно, это всего лишь предупреждение, а не ошибка.