Переопределение метода в C # - PullRequest
0 голосов
/ 16 июля 2011

Учитывая следующее:

class BC
{
  public void Display()
  {
     System.Console.WriteLine("BC::Display");
  }
}

class DC : BC
{
  new public void Display()
  {
     System.Console.WriteLine("DC::Display");
  }
}

class Demo
{
  public static void Main()
  {
     BC b;
     b = new BC();
     b.Display();    

     b = new DC();
     b.Display();    
  }
}

Я понимаю, что следующий код вызывает метод базового класса Display():

BC b;
b = new BC();
b.Display();  

И что следующие строки вызывают производный класс Display(), которая скрывает реализацию базового класса за счет использования ключевого слова new:

b = new DC();
b.Display(); 

Я хотел бы знать, что делает ключевое слово new внутри.

Источник этого кода содержал следующее объяснение:

Поскольку b содержит ссылку на объект типа DC, можно ожидать, что будет выполнена функция Display() класса DC.Но этого не происходит.Вместо этого выполняется Display() класса BC.Это потому, что функция вызывается на основе типа ссылки, а не на то, на что ссылается переменная ссылки b.Поскольку b является ссылкой типа BC, будет вызываться функция Display() класса BC независимо от того, на кого ссылается b.

Меня очень смущает этот конкретный бит: «потому что функция вызывается на основе типа ссылки, а не на то, что ссылочная переменная b ссылается на«

Что делает »функция вызывается в зависимости от типа ссылки "означает здесь

b = new DC();
b.Display();  

Какой тип b здесь?Он был объявлен как имя экземпляра класса BC, но позже b становится экземпляром класса DC.

Ответы [ 3 ]

8 голосов
/ 16 июля 2011

То, что вы делаете, это не переопределение, а затенение.Ключевое слово new позволяет вам иметь метод Display в обоих классах BC и DC, но методы вообще не связаны, они просто имеют одно и то же имя.

Чтобы переопределитьметод, вам нужно будет использовать ключевое слово virtual для метода в классе BC и метод overrides в классе DC.

Когда вы создаете теневой метод, это типссылки, которая решает, какой метод используется:

BC b1;
b1 = new BC();
b1.Display(); // Calls the method in BC

BC b2;
b2 = new DC();
b2.Display(); // Calls the method in BC

DC d1;
d1 = new DC();
d1.Display(); // Calls the method in DC

Переопределение метода выглядит следующим образом:

class BC {

  public virtual void Display() {
    System.Console.WriteLine("BC::Display");
  }

}

class DC : BC {

  override public void Display() {
    System.Console.WriteLine("DC::Display");
  }

}

При переопределении метода методы связаны, и это фактический типобъекта, который решает, какой метод использовать, а не тип ссылки:

BC b1;
b1 = new BC();
b1.Display(); // Calls the method in BC

BC b2;
b2 = new DC();
b2.Display(); // Calls the method in DC

DC d1;
d1 = new DC();
d1.Display(); // Calls the method in DC

Еще одно различие между переопределением и затенением заключается в том, что при затенении метода совсем не обязательно быть похожимключевое слово new просто сообщает компилятору, что вы хотите повторно использовать идентификатор для чего-то другого, чем в базовом классе.При переопределении метода сигнатуры метода должны быть одинаковыми.

Например, вы можете скрывать открытый метод, который принимает string, с чем-то совершенно другим, например, с частным свойством типа int:

public class X {

  public void XX(string z) { }

}

public class Y : X {

  private new int XX { get; set; }

}

X x = new Y();
x.XX();

Y y = new Y();
y.XX = 42;
4 голосов
/ 16 июля 2011

Я хотел бы знать, что новое ключевое слово делает внутри.

Вы не одиноки.См. Ответы на этот вопрос:

Путаница с виртуальным / новым / переопределением

и следующий вопрос:

Подробнее оВиртуальные / новые ... плюс интерфейсы!

для подробного, но все же высокоуровневого объяснения того, как реализованы виртуальные, новые, переопределения и реализация интерфейса.

0 голосов
/ 16 июля 2011

Сделайте Display виртуальной функцией в BC и переопределите в DC, тогда она будет работать так, как вы ожидаете.

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