В чем разница между переопределением (override), от перекрытия (new), наследуемого метода?
============================================================================================

 Доброго времени суток!   
  
**Условие:**  

Я имею родительский и дочерний от него методы, мне нужно изменить функционал унаследованного метода, для чего могу прибегнуть либо к переопределению уже имеющегося метода, либо перекрыть исходный новым.  
  
**Вопросы**  
1. Как можно визуализировать эти подходы? Override - зачеркиваю и пишу поверх, а New ?
2. Когда использовать переопределение, а когда перекрытие ?
3. Как компилятор преобразует код в обоих случаях ? Он по ключевому слову понимает, что нужно перезаписать (override), а что удалить (new) ?

  

Очень прошу, подкрепите ответ практическим примером (можно из вашего личного опыта). Заранее благодарю за внимание! 

 Сначала отвечу на третий вопрос.   

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

Компилятор создаёт [таблицу всех виртуальных методов](https://ru.wikipedia.org/wiki/%D0%A2%D0%B0%D0%B1%D0%BB%D0%B8%D1%86%D0%B0_%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2) класса (в том числе, переопределённых, потому что они тоже виртуальные) и указывает, в каком типе они обозначены. При вызове виртуального метода берётся реальный тип объекта и выбирается нужный вариант реализации метода.  

Если вы указываете в классе-наследнике метод с ключевым словом **new**, то этот метод перестаёт быть переопределением метода базового класса, и этот метод не добавляется в ту таблицу переопределений. Значит, при вызове метода поиск по типу объекта не найдёт метод, отмеченный **new** (его же нет в таблице), и попытается найти ближайший метод.  

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

2. Когда использовать переопределение, а когда перекрытие?  

Обычно нужно переопределение, перекрытие редко кому нужно. Если нужна отдельная реализация у конкретного наследника, то (иногда) можно сделать метод с другим именем, и вызывать напрямую, а не через вызов виртуальных методов. Если это всё-таки необходимо (перекрыть метод), то нужно понимать, что вызвать такой метод через ссылку на базовый класс не получится (без приведения к нужному типу).  
  

Интересно, что в Java все методы виртуальные, и нет возможности перекрыть (но не переопределить) базовый метод, как это можно в c#.   
  

1. Как можно визуализировать эти подходы?  

Этот вопрос непонятен. В графическом описании иерархии классов? В UML, насколько я помню, виртуальные методы пишутся курсивом. Значит, перекрытый метод будет обычным, не курсивным шрифтом.