как переопределить метод базового класса, вызываемый из конструктора - PullRequest
3 голосов
/ 24 ноября 2011

Я, вероятно, делаю это совершенно неправильно ..

public class BaseClass
{
  public string result { get; set; }

  public BaseClass(){}
  public BaseClass(string x) {
    result = doThing(x);
  }
  public virtual string doThing(string x)
  {
     return x;
  }
}



public class DerivedClass : BaseClass
{

  public DerivedClass(){}
  public DerivedClass(string x):base(x){}
  public override string doThing(string x)
  {
     return "override" + x;
  }
}

Я бы хотел, чтобы новый DerivedClass ("test") имел результат "overridetest", но это не так: он вызывает базовый метод doThing. Я что-то пропустил? Нужно ли создавать AbstractClass и наследовать от него и BaseClass, и DerivedClass, а класс Derived также переопределяет методы?

Ответы [ 4 ]

2 голосов
/ 24 ноября 2011

Вы не можете получить доступ к члену экземпляра подкласса из базового класса.

Он вызывает метод doThing базового класса, потому что это единственный доступный метод doThing, если базовый классобеспокоен.Если вы хотите, чтобы экземпляр каждого вызова класса представлял собственный метод doThing, в своем дочернем классе замените:

public DerivedClass(string x):base(x){}

на:

public DerivedClass(string x)
{
    doThing(x);
}
2 голосов
/ 24 ноября 2011

Проблема в том, что вы делаете виртуальный вызов в конструкторе.Механика этого вопроса и возможные обходные пути подробно описаны здесь .

Короче говоря, переопределенная функция еще не была создана при вводе конструктора базового класса, поэтому вызывается виртуальная функция в базовом классе.

0 голосов
/ 24 ноября 2011

Это потому, что ваш DerivedClass использует базовый конструктор и установит result как base.doThing("test"), что означает "тест".

, чтобы вы могли изменить DerivedClass на:

public class DerivedClass : BaseClass
{

  public DerivedClass(){}
  public DerivedClass(string x):base(x)
  {
     result="override"+x; 
     //or as result already be set as x, you can use: result="override" + result;
  }

}

или, как вы сказали,

необходимо создать AbstractClass и иметь оба BaseClass и DerivedClassунаследовать от этого, производный класс также переопределяет методы?

0 голосов
/ 24 ноября 2011

С точки зрения дизайна, вы всегда должны опасаться «делать вещи» во время вызова конструктора. Цель конструктора - просто привести экземпляр класса в допустимое состояние для будущего использования; он не должен пытаться «делать» что-либо еще или иметь другие побочные эффекты. Если создание вашего объекта является сложным делом, вы можете использовать шаблоны Builder или Factory, чтобы оградить вызывающий код от сложности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...