Как сохранить в свойство базового класса результат действий в производном
Подскажите как сделать так, чтобы после выполнения метода AddIngredient в свойство базового класса возвращалось значение для дальнейшего манипулирования с ним уже в базовом классе?
Есть базовый класс CoffeeMachine в котором находится свойство CoffeeBean
internal class CoffeeMachine
{
public int CoffeeBean { get; set; }
}
Так же есть производный класс Ingredients c методом AddIngredient
internal class Ingredients : CoffeeMachine
{
public void AddIngredient()
{
CoffeeBean += 900;
}
}
Ответы (2 шт):
Вам нужно более детально изучить наследование в C#. Наследование ещё называют "расширением базового класса". Что это значит? Это значит, что наследуемый/расширяемый класс будет иметь тот же функционал, что в базового, только до этого ещё добавится функционал текущего класса.
Как это всё на практики? Допустим вам нужно что-то сохранить или передать в базовый класс. У нас есть базовый класс:
public class BaseClass
{
public string Property { get; set; }
}
И наследуемый:
public class ChildClass : BaseClass
{
public void InvokeThisMethod(string toBase)
{
Property = toBase; // Here
}
}
Теперь разберём варианты, как это можно сделать другими способами, и что мы получаем из этого.
В дочернем классе мы можем использовать ключевое слово base, которое напрямую указывает на родительский элемент. Тогда вызова Property выглядел бы вот так:
base.Property = toBase;
Если вы хотите, что бы Property был доступен только для дочерних классов, вы можете использовать к нему модификатор доступа protected:
public class BaseClass
{
protected string Property { get; set; }
}
Тогда попытка вызова Property извне вызовет ошибку:
BaseClass baseClass = new BaseClass();
baseClass.Property = "Something"; // <-- Syntax error
Но синтаксис внутри ChildClass не потребует изменений и будет работать так само как и до этого
Общие соображения. А они похоже автору как раз таки и нужны. Потому что конкретное "решение" на кофе-машине и кофе-бобах тут вряд ли поможет. Ну потому что судя по тому как автор наследует "землекопа" от "кирпича" - тут всё гораздо глубже, и значит "смотреть" тут нужно гораздо глубже, чем это представляется автору.
То что хочет сделать автор - это переопределить метод базового класса. Простейший способ - это виртуализация метода базового класса.
Объявите метод базового класса - виртуальным. А затем переопределите этот метод в производном классе. И базовый класс будет "дёргать" как раз таки переопределённый метод в производном классе.
Как это работает на примере? Понятное дело что "трогать" кофе-машину и бобы - не стоит, там всё запущено. А вот например "потрогать" простейшие реализации виртуальных ToString(), GetHashCode(), Equals() - пожалуй можно. Это хорошие, годные примеры. И разобравшись в этом - автор разберётся и со своим "кофе".
Пример: Есть класс System.Object и у этого класса есть виртуальные методы. Это то, что нужно автору. Это например ToString(). Как это работает? ToString() в базовом классе System.Object - виртуальный. И может быть переопределён в производном классе. И этот метод возвращает строку. В базовый класс. Т.е. в производном классе можно переопределить ToString(). А базовый класс будет дёргать это переопределение метода, и базовый класс получит строку из производного класса.
public class Object
{
// Этот метод вызывается, когда нужно "строковое" представление объекта
// Этот метод может быть переопределён в производном классе
// Переопределённый метод (если он есть) будет вызываться, а не этот
// Вызов этого метода из базового класса будет дёргать переопределённый
// метод из производного класса, т.е. на самом деле выдернется
// строка из производного класса, а не строка "System.Object"
public virtual string ToString()
{
return "System.Object";
}
}
Производный класс от Object, с переопределённым ToString():
public class Derived : Object
{
// Переопределение метода, теперь ToString() другой
// Базовый Object будет пользовать именно этот переопределённый метод
// И получит переопределённую строку
public override string ToString()
{
// Переопределение строки, возвращает строку в базовый класс
return "Переопределение метода, возвращает переопределённую строку";
}
}
Метод для переопределения в базовом классе помечается как virtual. А переопределяемый метод в производном классе помечается как override. Обратите внимание.
А теперь всё то же самое можно сделать на кофе-машине и на кофе-бобах. Но это предлагается сделать автору самостоятельно. Автору нужно создать корректный родительский класс, там определить собственный виртуальный метод по бобам, затем создать производный класс и переопределить этот метод в производном классе. И получить значение этого метода (результат этого метода) в базовом классе.
П.С.: Наследовать ингредиенты от кофе-машины не следует. Ингредиенты и кофе-машина не являются прямыми наследниками/родителями друг относительно друга. П.П.С.: Объяснение на уровне "языка", но на самом деле на уровне "рантайма" - объяснение на уровне "языка" не годится. На уровне рантайма объяснение совершенно другое. Но оно здесь не нужно.