Почему базовый класс называется? - PullRequest
8 голосов
/ 30 апреля 2010

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

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.

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

Ответы [ 5 ]

17 голосов
/ 30 апреля 2010

Если вы сделаете name () virtual, а затем override в 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";
    }
}
6 голосов
/ 30 апреля 2010

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

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

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

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

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

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

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

3 голосов
/ 30 апреля 2010

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

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

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

class SpecialContainer: FuzzyContainer{
  override string GetName(){
   return base.GetName() + " Special Container";
  }
}
3 голосов
/ 30 апреля 2010

Это потому, что вы скрываете метод, а не отвергаете его. Без виртуального базового метода его невозможно переопределить, но вы можете «скрыть» его, создав метод с тем же именем.

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

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

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

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

0 голосов
/ 30 апреля 2010

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

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