Наследование в C# (Массивы обьектов)
Я немного упростил свой код чтоб мне могли обьяснить. Короче есть базовый клас Vegetable, и также Tomato, который наследуют базовый. Я создаю список типа Vegetable и добавляю туда обьекты типа Tomato, указывая в каждом количество помидорок (переменная quantity). Проблема заключаеться в конце, когда я пытаюсь вывести весь список обьектов с их соответствующим количеством. При дебаге увидел, что обьекты имеют 2 переменные:
quantity (Vegetable) [int]: 0 //это то, что выводит в конце
quantity [int]: 2 //тут как раз число, котороя я вводил
Обьясните, пожалуйста, почему в обьектах двое переменных, и как мне в конце вывести правильную переменную.
class Vegetable
{
public int quantity;
}
class Tomato : Vegetable
{
new public int quantity { get; set; }
}
class Program13
{
static void Main(string[] args)
{
List<Vegetable> vegetableList = new List<Vegetable>();
Tomato tomato1 = new Tomato();
Console.WriteLine("Write quantity of tomatoes1");
vegetableList.Add(tomato1);
tomato1.quantity = Convert.ToInt32(Console.ReadLine());
Tomato tomato2 = new Tomato();
Console.WriteLine("Write quantity of tomatoes2");
vegetableList.Add(tomato2);
tomato2.quantity = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Salad contains:");
foreach (var obj in vegetableList)
{
Console.WriteLine($"{obj.quantity} {obj.GetType()}");
}
} }
Выводит это: Salad contains:
0 Tomato
0 Tomato
Ответы (1 шт):
вы используете "сокрытие", то есть ваше свойство new public int quantity { get; set; } как бы скрывает поле public int quantity; (см про оператор new). При сокрытии по сути оба quantity остаются, какой из них будет вызван зависит от типа переменной.
То есть вот тут myObject.quantity - если переменная myObject имеет тип Vegetable - то будет из него использоваться поле, если же myObject имеет тип Tomato - то оттуда.
Вообще это редко когда имеет смысл так делать. Обычно, если надо переопределить что то в производном классе, то в базовом это чтото (свойство или метод, например) объявляют виртуальными (virtual) и в производных классах уже перегружают (override). В этом случае тип переменной не важен, всегда будет вызываться код производного класса.
Пример
class Vegetable
{
public virtual int quantity { get; set; }
}
class Tomato : Vegetable
{
public override int quantity { get; set; }
}
Проверка
List<Vegetable> vegetableList = new List<Vegetable>();
Tomato tomato1 = new Tomato();
tomato1.quantity = 10;
vegetableList.Add(tomato1);
Console.WriteLine("Salad contains:");
foreach (var obj in vegetableList)
{
Console.WriteLine($"{obj.quantity} {obj.GetType().Name}");
}
Вывод
Salad contains:
10 Tomato
Конечно, пример искусственный, так как на практике нет смысла перегружать что то, если в перегрузке логика никак не отличается, но суть ясна я думаю.