У вас почти правильная настройка метода, хотя вам нужно внести еще несколько изменений. Вам нужно, чтобы базовый класс представлял DoStuff () как виртуальный метод. Попробуйте это:
public abstract class Command
{
public string keyword;
public int globalCooldown;
//List<string> args;
public abstract void DoStuff(List<string> args);
}
public class DoStuffA : Command
{
//public string keyword = "pleasedostuffa";
//public int globalCooldown = 2;
//args = _args;
public DoStuffA()
{
keyword = "pleasedostuffa";
globalCooldown = 2;
}
public override void DoStuff(List<string> args)
{
//doing stuff A here with all the logic and so on
}
}
public class DoStuffB : Command
{
//public string keyword = "pleasedostuffb";
//public int globalCooldown = 8;
// args = _args;
public DoStuffB()
{
keyword = "pleasedostuffb";
globalCooldown = 8;
}
public override void DoStuff(List<string> args)
{
//doing stuff B here with all the logic and so on
}
}
Итак, пара заметок.
Метод наследования
Здесь я делаю базовый класс абстрактным, просто чтобы убедиться, что каждая дочерняя команда реализует абстрактную функцию DoStuff()
. В конце концов, что бы вы сделали с экземпляром базового класса? Это ничего не сделает, потому что у вас нет реальной реализации. Таким образом, абстрактный помогает избежать случайного создания экземпляра самой команды, а также обеспечивает правильную работу реализаторов подтипов.
Во-вторых, на уровне дочернего класса вам необходимо override
метод базового класса. Это гарантирует, что все, что вызывает ((Command)doStuffB).DoStuff()
, получит правильную реализацию функции.
Теперь, когда у вас есть метод DoStuff () для Command, ваш цикл foreach
должен работать так, как вы ожидаете. У вас есть метод, доступный в базовом классе, поэтому виртуальные переопределения на дочернем уровне можно запускать без приведения.
Доступ к базовому классу
Поля, которые вы пытаетесь объявить здесь, keyword
и globalCooldown
, - это не то, как люди обычно предоставляют такую информацию, но прежде чем мы перейдем к этому, я собираюсь объяснить более фундаментальный принцип доступа члены базового класса из унаследованных классов.
Эти два поля должны быть помечены public
(и им дан правильный тип), чтобы их можно было использовать вне класса (в вашем foreach). Ключевое слово public
называется модификатором доступности, и есть несколько других вариантов доступности, но в вашем случае только public
может делать то, что вы хотите.
Как видите, я закомментировал поля в дочерних классах. Если вы объявите их там, они будут скрывать (но не переопределять) элементы с одинаковыми именами в базовом классе. Для полей нет эквивалента virtual
или abstract
, поэтому вам нужна другая стратегия. Здесь мы оставляем исходное объявление этих полей в базовом классе, чтобы они были доступны любому объекту, содержащему любой тип команды. Но вместо того, чтобы перемаркировать их на уровне дочернего класса, мы просто устанавливаем значения членов базового класса в конструкторе для дочерних классов.
Обратите внимание, что для ясности, вы можете явно указать, что вы устанавливаете член в базовом классе, используя вместо этого base.keyword = "etc";
.
Предоставление внутренних значений через свойства
Как я уже отметил, это будет работать, но не совсем так, как большинство людей выставляют значения keyword
и globalCooldown
. Для этого вы обычно используете свойство. Это позволяет хранить и открывать значения, не рискуя позволить кому-либо изменить значение (преднамеренно или непреднамеренно). В этом случае вы хотите объявить свойство следующим образом:
public string Keyword // properties start with a capital letter by convention
{
get; // The get accessor is public, same as the overall property
protected set; // the set accessor is protected
}
Метод доступа protected
означает, что он все еще доступен для установки дочерними классами, но не кем-либо еще. Это, вероятно, то, что вы хотите. Итак, теперь в вашем дочернем конструкторе вы можете установить base.Keyword = "whatever";
, и ваш код foreach
может ссылаться, но не перезаписывать это значение. Вы можете объявить GlobalCooldown аналогичным образом.