Почему базовый класс называет?

Вот моя ситуация:

interface Icontainer{
 string name();
}

abstract class fuzzyContainer : Icontainer{
  string name(){
   return "Fuzzy Container";
  }
}

class specialContainer: fuzzyContainer{
  string name(){
   return base.name() + " Special Container";
  }
}


Icontainer cont = new SpecialContainer();
cont.name(); // I expected "Fuzzy Container Special Container" as the output.

Когда я работаю, мой код, как описано выше вывода является просто "Нечетким Контейнером". Что я пропускаю здесь? Существует ли лучший способ получить желаемые результаты?

8
задан Nat Ritmeyer 21 September 2015 в 08:25
поделиться

5 ответов

Если вы сделаете name () virtual , а затем переопределите в specialContainer, вы получите ожидаемое поведение.

public interface Icontainer
{
    string name();
}

public abstract class fuzzyContainer : Icontainer
{
    public virtual string name()
    {
        return "Fuzzy Container";
    }
}

public class specialContainer : fuzzyContainer
{
    public override string name()
    {
        return base.name() + " Special Container";
    }
}
17
ответ дан 5 December 2019 в 05:44
поделиться

Во-первых, это полезно, когда у вас есть вопросы, когда вы публикуете код, который действительно компилируется. Трудно проанализировать проблему, когда она полна пропущенных модификаторов и опечаток, трудно понять, является ли проблема опечаткой или нет.

Как только мы выполним работу по исправлению вашей программы, чтобы она действительно компилировалась, компилятор выдает предупреждение о том, что перегрузка выглядит неправильно . Поскольку ваш вопрос - "почему неправильная перегрузка?" Вероятно, было бы неплохо прочитать предупреждение компилятора, которое мы выпустили, чтобы вы могли проанализировать эту проблему.

Проблема в том, что производный класс содержит новый метод с именем «name», а не переопределение существующего метода. Это то, что вам пытается сказать предупреждение.

Есть два способа решить эту проблему, в зависимости от того, вы предполагали, что метод будет «новым» или «переопределенным». Если вы намеревались «переопределить» метод, сделайте базовую реализацию виртуальной, а производную реализацию - переопределением.

Если вы предполагали, что метод будет «новым» и , вы все равно хотите, чтобы новый метод заменил привязку к реализации интерфейса , тогда используйте повторную реализацию интерфейса :

class SpecialContainer: FuzzyContainer, IContainer 
{
  public new string Name()
  { 
    return base.Name() + " Special Container"; 
  } 
} 

Обратите внимание на "новый" и тот факт, что мы повторно заявили , что этот класс реализует IContainer. Это говорит компилятору «игнорировать привязки к методам IContainer, выведенные из базового класса, и начать заново."

6
ответ дан 5 December 2019 в 05:44
поделиться

Это потому, что вы скрываете метод, а не переопределяете его. Не сделав базовый метод виртуальным, невозможно его переопределить, но вы можете "спрятать" его, создав одноименный метод.

Если у вас было:

SpecialContainer cont = new SpecialContainer();
cont.name();

Тогда вы также получите ожидаемый результат.

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

3
ответ дан 5 December 2019 в 05:44
поделиться

Метод name в этом классе не является переопределением метода FuzzyContainer Name. Поэтому, когда вы приводите объект specialContainer в качестве IContainer, он может вызывать только метод Name базового класса.

0
ответ дан 5 December 2019 в 05:44
поделиться

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

Я также взял на себя смелость "подправить" ваш код в соответствии с наиболее распространенными соглашениями об именовании.

abstract class FuzzyContainer : IContainer{
  protected virtual string GetName(){
   return "Fuzzy Container";
  }
}

class SpecialContainer: FuzzyContainer{
  override string GetName(){
   return base.GetName() + " Special Container";
  }
}
3
ответ дан 5 December 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: