#c# #inheritance #interface
#c# #наследование #интерфейс
Вопрос:
Мне интересно, может ли кто-нибудь, пожалуйста, объяснить это мне:
class Program
{
static void Main()
{
AnotherDerivedClass d = new AnotherDerivedClass();
Console.WriteLine(d.PrintMessage());
IMsg m = d as IMsg;
//Why this prints BaseClass.
//How does it know that IMsg is implemented in the BaseClass.
Console.WriteLine(m.PrintMessage());
IMsg n = d as DerivedClass;
//Why this prints BaseClass and not DerivedClass
Console.WriteLine(n.PrintMessage());
Console.Read();
}
}
public interface IMsg
{
string PrintMessage();
}
public class BaseClass : IMsg
{
public string PrintMessage()
{
return "BaseClass";
}
}
public class DerivedClass : BaseClass
{
public new string PrintMessage()
{
return "DerivedClass";
}
}
public class AnotherDerivedClass : DerivedClass
{
public new string PrintMessage()
{
return "AnotherDerivedClass";
}
}
Комментарии:
1. Какой у вас вопрос? … Ах, я вижу, у вас есть вопросы в виде комментариев к вашему коду 🙂
2. Гораздо лучше задавать вопросы в теле вопроса, а не в комментариях к коду, поскольку люди просматривают списки кодов в поисках вопроса…
3. Я подумал, что людям будет легко понять, что я хочу понять, если я задам вопрос в комментарии к коду.
Ответ №1:
Вы заменили реализацию в своих производных классах, а не переопределили их. Если вы используете BaseClass
, будет использована оригинальная реализация.
Вам нужно сделать метод в базовом виртуальном:
public class BaseClass : IMsg
{
public BaseClass()
{
}
public virtual string PrintMessage()
{
return "BaseClass";
}
}
и переопределение в производном классе:
public class DerivedClass : BaseClass
{
public DerivedClass()
{
}
public override string PrintMessage()
{
return "DerivedClass";
}
}
чтобы получить указанное вами поведение.
Комментарии:
1. Насколько я понимаю, ключевое слово «New» скроет реализацию базового класса. Итак, если реализация базового класса скрыта, не предполагается ли вызвать новую реализацию?
2. @Asdfg, это не так работает. Используйте
new
, когда базовый метод не выполняет то, что вы хотите, и он не являетсяvirtual
и не может быть переопределен. Однако это только скрывает базовую реализацию, пока вы работаете со ссылкой на производный тип. Ссылки на объект через базовый класс будут продолжать использовать базовое поведение. Вот почему абсолютно предпочтительно использоватьvirtual
модификатор для базовых методов, которые вы действительно собираетесь переопределить в производных классах.