Как посмотреть перегрузки методов в visual studio
Полиморфизм – соль ООП. Перегрузка (overload) и переопределение (override) – два инструмента достижения полиморфного поведения в Java.
Перегрузкой реализуется ad-hoc-полиморфизм. Это значит «один и тот же» метод может работать с разными параметрами. С технической точки зрения это просто два разных метода, сигнатуры которых имеют одинаковое название, но разный набор параметров. Важно помнить, что для перегрузки не достаточно различий только модификаторов, возвращаемых типов и списков исключений.
Ad-hoc – не совсем настоящий полиморфизм, так как при нём используется раннее, или статическое связывание (early binding, static dispatch). Это значит, что для выбора конкретного варианта метода используется информация о типе переменной, а не объекта в ней лежащего, и происходит это еще при компиляции.
Если в классе объявлены два перегруженных метода, а аргумент в вызове подходит под оба, случится ошибка компиляции. В примере ниже компилятор не может выбрать между вариантами метода println с параметром char[] и со String , так как null может быть и тем и другим.
Переопределение (override) дает полиморфизм подтипов. Это реализация/подмена метода нефинального родительского класса или интерфейса. С помощью этого механизма достигается поведение, когда экземпляр хранится под типом родителя, но реализация методов используется специфичная для этого конкретного подтипа. Пример:
Здесь метод add вызывается общий для всех списков, но добавлен будет именно элемент связного списка.
Выбор конкретного метода происходит в последний момент, в процессе работы программы, в зависимости от типа объекта. Это называется позднее или динамическое связывание методов (late binding, dynamic dispatch).
Переопределение имеет непосредственное отношение к принципу подстановки Лисков (LSP): в хорошем объектно-ориентированном коде для вызывающего кода переопределенный метод не должен быть отличим от оригинального.
Переопределенный метод принято снабжать аннотацией @Override . Ее отсутствие допускается, но компиляция не перегружающего метода с такой аннотацией приведет к ошибке.
При переопределении можно сузить набор выбрасываемых исключений или тип результата, и заменить модификатор доступа на менее строгий.
Перегрузка и переопределение методов в Java
Изучите основы перегрузки и переопределения методов в Java.
1. Обзор
Перегрузка и переопределение методов являются ключевыми понятиями языка программирования Java, и как таковые они заслуживают углубленного изучения.
В этой статье мы изучим основы этих концепций и посмотрим, в каких ситуациях они могут быть полезны.
2. Перегрузка метода
Перегрузка методов-это мощный механизм, который позволяет нам определять API-интерфейсы связного класса. Чтобы лучше понять, почему перегрузка методов является такой ценной функцией, давайте рассмотрим простой пример.
Предположим, что мы написали наивный служебный класс, который реализует различные методы умножения двух чисел, трех чисел и так далее.
Если мы дали методам вводящие в заблуждение или двусмысленные имена, такие как multiply 2() , multiply 3() , multiply 4 (), , то это будет плохо спроектированный API класса. Здесь в игру вступает перегрузка методов.
Проще говоря, мы можем реализовать перегрузку метода двумя различными способами:
- реализация двух или более методов , которые имеют одно и то же имя, но принимают разное количество аргументов
- реализация двух или более методов , которые имеют одно и то же имя, но принимают аргументы разных типов
2.1. Различное количество аргументов
Класс Multiplier в двух словах показывает, как перегрузить метод multiplier () , просто определив две реализации, которые принимают разное количество аргументов:
2.2. Аргументы различных типов
Аналогично, мы можем перегрузить метод multiply () , заставив его принимать аргументы разных типов:
Кроме того, правомерно определить класс Multiplier с обоими типами перегрузки методов:
Однако стоит отметить, что невозможно иметь две реализации методов, которые отличаются только типами возвращаемых значений .
Чтобы понять, почему – давайте рассмотрим следующий пример:
2.3. Тип Продвижения
Одной из отличительных особенностей, обеспечиваемых перегрузкой методов, является так называемое продвижение типа , также известное как расширение примитивного преобразования .
Проще говоря, один данный тип неявно повышается до другого, когда нет соответствия между типами аргументов, переданных перегруженному методу, и конкретной реализацией метода.
Чтобы более четко понять, как работает продвижение типов, рассмотрим следующие реализации метода multiply() :
Теперь вызов метода с двумя аргументами int приведет к тому, что второй аргумент будет повышен до long , так как в этом случае нет соответствующей реализации метода с двумя взаимозаменяемыми аргументами.
Давайте посмотрим быстрый модульный тест, чтобы продемонстрировать продвижение типа:
И наоборот, если мы вызываем метод с соответствующей реализацией, продвижение типа просто не происходит:
Вот краткое описание правил продвижения типов, которые применяются для перегрузки методов:
- байт может быть повышен до short, int, long, float, или double
- short может быть повышен до int, long, float, или double
- char может быть повышен до int, long, float, или double
- он может быть повышен до long, float, или double
- long может быть повышен до float или double
- float может быть повышен до double
2.4. Статическая привязка
Возможность связать конкретный вызов метода с телом метода называется связыванием.
В случае перегрузки метода привязка выполняется статически во время компиляции, поэтому она называется статической привязкой.
Компилятор может эффективно установить привязку во время компиляции, просто проверив сигнатуры методов.
3. Переопределение метода
Переопределение методов позволяет нам предоставлять детальные реализации в подклассах для методов, определенных в базовом классе.
В то время как переопределение метода является мощной функцией – учитывая , что это логическое следствие использования наследования , один из самых больших столпов ООП – когда и где его следует использовать, следует тщательно анализировать на основе каждого случая использования .
Вот базовый класс:
А вот надуманный подкласс:
В приведенной выше иерархии мы просто переопределили метод accelerate () , чтобы обеспечить более точную реализацию подтипа Car.
Здесь ясно видно, что если приложение использует экземпляры класса Vehicle , то оно также может работать с экземплярами Car , поскольку обе реализации метода accelerate () имеют одинаковую сигнатуру и один и тот же тип возвращаемого значения.
Давайте напишем несколько модульных тестов для проверки классов Vehicle и Car :
Теперь давайте посмотрим некоторые модульные тесты, которые показывают, как методы run() и stop () , которые не переопределены, возвращают равные значения для обоих Car и Vehicle :
В нашем случае у нас есть доступ к исходному коду для обоих классов, поэтому мы можем ясно видеть, что вызов метода accelerate() на базовом экземпляре Vehicle и вызов accelerate() на экземпляре Car вернет разные значения для одного и того же аргумента.
Таким образом, следующий тест демонстрирует, что переопределенный метод вызывается для экземпляра Car :
3.1. Взаимозаменяемость Типов
Основным принципом в ООП является принцип подстановки типов, который тесно связан с принципом подстановки Лискова (LSP) .
Проще говоря, LSP утверждает, что если приложение работает с заданным базовым типом, то оно также должно работать с любым из его подтипов . Таким образом, заменяемость типов должным образом сохраняется.
Самая большая проблема с переопределением методов заключается в том, что некоторые конкретные реализации методов в производных классах могут не полностью соответствовать LSP и, следовательно, не сохранять заменяемость типов.
Конечно, допустимо сделать переопределенный метод, чтобы принимать аргументы разных типов и возвращать другой тип, но при полном соблюдении этих правил:
- Если метод в базовом классе принимает аргументы заданного типа, переопределенный метод должен принимать тот же тип или супертип(он же контравариантные аргументы метода)
- Если метод в базовом классе возвращает void , переопределенный метод должен возвращать void
- Если метод в базовом классе возвращает примитив, переопределенный метод должен возвращать тот же примитив
- Если метод в базовом классе возвращает определенный тип, переопределенный метод должен возвращать тот же тип или подтип (он же ковариантный возвращаемый тип)
- Если метод в базовом классе вызывает исключение, переопределенный метод должен вызывать то же исключение или подтип исключения базового класса
3.2. Динамическая привязка
Учитывая, что переопределение метода может быть реализовано только с наследованием, где существует иерархия базового типа и подтипов, компилятор не может определить во время компиляции, какой метод вызывать, поскольку и базовый класс, и подклассы определяют одни и те же методы.
Как следствие, компилятору необходимо проверить тип объекта, чтобы узнать, какой метод следует вызывать.
Поскольку эта проверка происходит во время выполнения, переопределение метода является типичным примером динамической привязки.
4. Заключение
В этом уроке мы узнали, как реализовать перегрузку методов и переопределение методов, а также рассмотрели некоторые типичные ситуации, в которых они полезны.
Как обычно, все примеры кода, показанные в этой статье, доступны на GitHub .
Вводный курс. Язык программирования Java
Чтобы избежать дублирования методов, Java позволяет определять несколько методов с одним и тем же именем. Например, удобно, чтобы методы, которые реализуют похожий алгоритм для различных типов данных, или разного их количества имели одно и то же имя. Например:
int max(int x, int y)
int max(int x, int y, int z)
float max(float x, float y)
float max(float x, float y, float z).
При компиляции программы при обращении к методу max() в зависимости от типа и количества фактических параметров будет вызван требуемый метод.
для max(1, 2) будет вызван метод max(int x, int y),
для max(1.0, 2.0) будет вызван метод max(float x, float y).
Предоставление компилятору возможности выбора среди нескольких методов необходимого называется перегрузкой (overload). В процессе такого выбора используется понятие сигнатуры метода. В Java сигнатура метода состоит из имени метода, типа, числа и последовательности формальных параметров метода.
Имена параметров, тип возвращаемого значения, модификаторы доступа в сигнатуру не входят, например методы
publicl void draw( int x, int y)
public int draw( int color, int bkcolor)
abstract void draw (int a, int b)
имеют одинаковую сигнатуру, поскольку сигнатуру составляют: имя метода — draw, тип, число параметров и их последовательность — (int, int):
draw (int, int)
draw (int, int)
draw (int, int).
- Перегрузка методов позволяет использовать одно и то же имя для нескольких методов с разными сигнатурами.
- Для перегрузки методов необходимо определить методы с одним и тем же именем, которые отличаются:
- количеством параметров
- типом параметров
- последовательностью типов параметров
Переопределение методов (override)
Переопределение – это изменение реализации уже существующего в суперклассе м етода (override). В новом методе должны быть те же сигнатура и тип возвращаемого результата, что и у метода родительского класса.
Имеем родительский класс A, в нем определен метод message() . В подклассе В родительский метод переопределен.
Будет выведено:
Класс A
Класс В
Запись @Override называется аннотацией и указывает, что метод базового класса должен быть переопределен. Если в базовом классе не окажется метода с аналогичной сигнатурой, то мы получим предупреждение компилятора о том, что метод переопределить невозможно. Аннотация не влияет на переопределение метода, но служит лишь для контроля успешности переопределения. Аннотацию можно удалить, но этого делать не надо, потому что в случае ошибки вместо переопределения будет выполнена перегрузка метода.
Я хотел бы проверить, как быстро работает моя функция проектов. Было бы здорово, если бы была возможность отмечать медленные места моей функции, чтобы я мог изменить свой код для повышения производительности. Я использую Microsoft Visual Studio 2012, и я знаю, что есть встроенный инструмент тестирования, но я действительно не знаю, где его найти и, вероятно, как его использовать. Было бы здорово, если бы кто-то мог помочь мне с этой проблемой.
для тестирования метода excecution время вы можете использовать Секундомер Класс.
также есть встроенный профилировщик в VS 2013 в разделе Анализ = > меню профилировщика. Я не помню, в какой версии VS он был добавлен, но я думаю, что он есть в VS 2012. Таким образом, вы можете начать профилирование, некоторое время использовать приложение, а затем проверить, какие операции заняли больше времени.
обновление: VS 2017 теперь показывает время выполнения в миллисекундах для каждой строки или когда Выполнить Команду используется во время сеанса отладки:
В Visual Studio 2013
в верхнем меню выберите ANALYZE -> Performance and Diagnostics
Проверьте мастер производительности, чтобы рассчитать необходимое время. нажать пуск. Теперь выберите-Instrumentation для измерения вызовов функций и подсчета. Нажимать далее. Выберите-будет показан один или несколько доступных проектов с таким именем проекта. Нажимать далее. Снова нажмите кнопку Далее. Проверить - запустить профилирование после завершения работы мастера. Теперь нажмите кнопку Готово.
В Visual Studio 2017
в верхнем меню выберите ANALYZE -> Performance Profiler
Проверьте мастер производительности, чтобы рассчитать необходимое время. нажать пуск. Теперь выберите-Instrumentation для измерения вызовов функций и подсчета. Нажимать далее. Выберите-будет показан один или несколько доступных проектов с таким именем проекта. Нажимать далее. Снова нажмите кнопку Далее. Проверить - запустить профилирование после завершения работы мастера. Теперь нажмите кнопку Готово.
если у вас возникли проблемы с использованием мастера производительности в Windows 10, см.:метод выборки процессора отключен в профилировщике производительности.
вы найдете мастер производительности в меню анализ, если у вас есть достаточно хорошая версия Visual Studio (Professional?).
Он измеряет время, затрачиваемое на каждый используемый метод, и статистика дает вам хороший обзор возможных узких мест.
в Visual Studio содержит много хороших встроенных инструментов для профилирования, и многие другие доступны в виде плагинов (также бесплатно).
Как только код был написан, единственный способ, который я знаю, чтобы просмотреть перегрузки для метода, - это фактически отредактировать метод, удалив скобки () и снова открыть их.
есть ли сочетание клавиш, которое я мог бы нажать, чтобы активировать это вместо того, чтобы редактировать мои файлы?
для примера, пожалуйста, обратитесь к Showdialog Метод Перегрузки скриншоте ниже:
попробуйте сочетание клавиш Ctrl - Shift - пробел . Это соответствует Edit.ParameterInfo , Если вы изменили значение по умолчанию.
пример:
Ctrl + Shift + пробел показывает Edit.ParameterInfo для выбранного метода, и под выбранным методом я имею в виду, что курсор находится в скобках метода.
и для тех, кто все еще используя 2008.
протестировано только в Visual Studio 2010.
поместите курсор в (), нажмите Ctrl + K , потом P .
Теперь перейдите, нажав ↑ / ↓ клавиши со стрелками.
привязка ключа по умолчанию для этого - Ctrl + Shift+Пробел
основная команда Visual Studio - Edit.ParameterInfo . Если стандартная привязка ключей не работает для вас (возможно, в некоторых профилях), вы можете изменить ее через страницу параметров клавиатуры
- Сервис -> Параметры
- клавиатура
- введите Edit.Свойства parameterinfo
- изменить сочетание клавиш
- Нажмите Назначить
случается, что ни один из вышеперечисленных методов работы. Привязка ключа правильная, но подсказка инструмента просто не показывает в любом случае, ни как помощь завершения, ни по требованию.
Отличный вопрос; у меня была та же проблема. Оказывается, действительно есть сочетание клавиш для вызова этого списка: Ctrl+Shift+Space (вариант основного сочетания клавиш IntelliSense Ctrl+Space).
команда Edit.ParameterInfo (сопоставляется Ctrl + Shift + пробел по умолчанию) покажет подсказку перегрузки, если она вызывается, когда курсор находится внутри скобок параметров вызова метода.
команда Edit.QuickInfo (сопоставляется Ctrl + K Ctrl + Я по умолчанию) покажет подсказку, которую вы увидите, если наведете курсор местоположение.
время от времени предложения выше перестают работать, если я перезапущу Visual Studio, они снова начнут работать.
Я знаю, что это старый пост, но для новичков, таких как я, которые все еще попадают на эту страницу, это может быть полезно. когда вы наводите курсор на метод, вы получаете не кликабельное информационное поле, тогда как если вы просто напишите запятую в скобках метода, IntelliSense предложит вам любимое информационное поле с кликабельными стрелками.
есть ли какой-либо инструмент, который я могу использовать для просмотра значений переменных, как код выполняется в VS?
прямо сейчас я могу видеть их только тогда, когда я держу точку останова.Но проблема в том, что код отлично работает, когда я держу точку останова.она портится, только когда бежит быстро.
любая помощь будет оценили.
вы можете просматривать переменные только при наличии точки останова, однако вы можете просто вручную записать значения переменных в окно вывода Visual Studios:
Я мое мнение, а не устанавливать точки останова, вы можете использовать Debug.Write(yourVariable) в режиме отладки, так что вы можете посмотреть его значение в окно вывода.
Похоже, вам нужна условная точка останова. Помимо печати значений (консоль, вывод отладки, трассировка) по мере выполнения кода нет ничего, что покажет вам живые данные достаточно медленно, чтобы вы могли их увидеть. Поместите условный оператор в обнаружение, когда значения больше не являются допустимыми, и вставьте программную точку останова на этом.
использовать Debug.Write для вывода переменных. Можно также использовать профилировщик.
все вышеупомянутые методы (сброс в консоль, используя Debug.Пишите, логирование и т. д. так далее.) сбросить содержимое переменных будет делать трюк .
из вашего описания проблемы (т. е. ". отлично работает с точками останова, терпит неудачу, когда остается один для запуска. "), похоже, у вас есть потоковый сценарий с проблемами синхронизации. Если это так, проверка используемых методов синхронизации может дать лучшие результаты.
в visual studio 2010 (возможно, в более ранних версиях я не проверял) условная точка останова может быть установлена для печати значения переменной и продолжения работы. Это делается, щелкнув правой кнопкой мыши точку останова и выбрав "при попадании". Затем открывается диалоговое окно, в котором можно указать, что и как печатать. Он отлично работал для меня в родном проекте C.
Visual Studio: как показать перегрузки в IntelliSense?
Как только код был написан, единственный способ узнать перегрузки для метода — это фактически отредактировать метод, удалив Parenthesis () и снова его запустив.
Есть ли клавиша быстрого доступа, которую я мог бы нажать, чтобы активировать это вместо того, чтобы редактировать мои файлы?
Для примера обратитесь к экрану ShowDialog Overload:
Попробуйте сочетание клавиш Ctrl — Shift — Space . Это соответствует Edit.ParameterInfo , если вы изменили значение по умолчанию.
Пример:
Ctrl + Shift + Space показывает Edit.ParameterInfo для выбранного метода, и под выбранным методом я имею в виду, что каретка должна находиться в скобках метода.
И для тех, кто все еще использует 2008.
Проверено только на Visual Studio 2010.
Поместите курсор в поле(), нажмите Ctrl + K , затем P .
Теперь перемещайтесь, нажимая клавиши со стрелками ↑ / ↓ .
Связывание по умолчанию для этого — Ctrl+Shift+Space
Основная команда Visual Studio — Edit.ParameterInfo . Если стандартное связывание ключей не работает для вас (возможно в некоторых профилях), вы можете изменить его с помощью страницы параметров клавиатуры
Случается, что ни один из вышеперечисленных методов не работает. Связывание ключей является правильным, но подсказка инструмента просто не отображается ни в коем случае, ни в качестве справки по завершению, ни по требованию.
Отличный вопрос; Я была такая же проблема. Оказывается, что на самом деле есть ярлык для вызова этого списка: Ctrl + Shift + Space (вариация основного ярлыка IntelliSense Ctrl + Space).
Visual Studio: как показать перегрузки в IntelliSense?
После написания кода единственный известный мне способ просмотреть перегрузки для метода — это отредактировать метод, удалив скобку () и снова открыв их.
Есть ли горячая клавиша, которую я мог бы нажать, чтобы активировать это, вместо того, чтобы редактировать мои файлы?
В качестве примера см. Снимок экрана ShowDialog Overload ниже:
Попробуйте сочетание клавиш Ctrl — Shift — Пробел . Это соответствует Edit.ParameterInfo , если вы изменили значение по умолчанию.
Примере:
Моя появилась в VS2010 после написания первой скобки ..
Итак, детские коляски.Добавить (
После того, как проделал что-то подобное, появилось поле со стрелками вверх и вниз.
Я знаю, что это старый пост, но для новичков вроде меня, которые все еще посещают эту страницу, это может быть полезно. когда вы наводите указатель мыши на метод, вы получаете информационное окно, которое не является интерактивным, тогда как если вы просто напишите запятую в скобках метода, IntelliSense предложит вам любимое информационное окно с интерактивными стрелками.
Время от времени приведенные выше предложения перестают работать, но если я перезапускаю Visual Studio, они снова начинают работать.
Команда Edit.ParameterInfo (по умолчанию сопоставлена Ctrl + Shift + Space ) покажет всплывающую подсказку перегрузки, если она вызывается при наведении курсора находится внутри скобок параметров при вызове метода.
Команда Edit.QuickInfo (по умолчанию сопоставленная Ctrl + K Ctrl + I ) покажет всплывающая подсказка, которую вы увидите, если наведете курсор мыши на местоположение курсора.
Отличный вопрос; Я была такая же проблема. Оказывается, действительно существует сочетание клавиш для вызова этого списка: Ctrl + Shift + Пробел (вариант основного сочетания клавиш IntelliSense для Ctrl + Пробел).
Бывает, что ни один из вышеперечисленных способов не работает. Привязка клавиш правильная, но всплывающая подсказка просто ни в коем случае не отображается ни в качестве справки по завершению, ни по запросу.
Привязка клавиш по умолчанию для этого — Ctrl + Shift + Space . Базовая команда Visual Studio — Edit.ParameterInfo .
Если стандартная привязка клавиш не работает для вас (возможно в некоторых профилях), вы можете изменить ее на странице параметров клавиатуры.
Перегруженные свойства и методы (Visual Basic)
Перегрузка — это создание более чем одной процедуры, конструктора экземпляра или свойства в классе с тем же именем, но разными типами аргументов.
Перегрузка использования
Перегрузка особенно полезна, когда объектная модель определяет, что для процедур, которые работают с различными типами данных, используются одинаковые имена. Например, класс, который может отображать несколько различных типов данных, может иметь Display процедуры, которые выглядят следующим образом:
Без перегрузки необходимо создать разные имена для каждой процедуры, даже если они выполняют одно и то же действие, как показано далее:
Перегрузка упрощает использование свойств или методов, поскольку она предоставляет возможность выбора типов данных, которые можно использовать. Например, перегруженный Display метод, описанный ранее, можно вызвать с помощью любой из следующих строк кода:
во время выполнения Visual Basic вызывает правильную процедуру на основе типов данных указанных параметров.
Перегрузка правил
Перегруженный член класса создается путем добавления двух или более свойств или методов с одинаковым именем. За исключением перегруженных производных членов, каждый перегруженный член должен иметь разные списки параметров, и следующие элементы нельзя использовать в качестве отличительной функции при перегрузке свойства или процедуры:
Модификаторы, такие как ByVal или ByRef , которые применяются к элементу или параметрам элемента.
Типы возвращаемых процедур
Overloads Ключевое слово является необязательным при перегрузке, но если какой-либо перегруженный член использует Overloads ключевое слово, то все другие перегруженные члены с тем же именем также должны указывать это ключевое слово.
Производные классы могут перегружать унаследованные члены с элементами, которые имеют одинаковые параметры и типы параметров, процесс, называемый теневым именем и сигнатурой. Если Overloads ключевое слово используется при затенении по имени и сигнатуре, реализация члена в производном классе будет использоваться вместо реализации в базовом классе, а все другие перегрузки для этого члена будут доступны экземплярам производного класса.
Если Overloads ключевое слово пропущено при перегрузке унаследованного члена с членом, имеющим идентичные параметры и типы параметров, перегрузка называется тенью по имени. Затенение по имени заменяет унаследованную реализацию члена и делает все другие перегрузки недоступными для экземпляров производного класса и его децедентс.
Overloads Shadows Модификаторы и не могут использоваться одновременно с одним свойством или методом.
Пример
В следующем примере создаются перегруженные методы, которые принимают String или Decimal представление суммы в долларе и возвращают строку, содержащую налог на продажу.
Использование этого примера для создания перегруженного метода
Откройте новый проект и добавьте класс с именем TaxClass .
Добавьте в класс TaxClass приведенный далее код.
Добавьте следующую процедуру в форму.
Добавьте в форму кнопку и вызовите ShowTax процедуру из Button1_Click события кнопки.
Запустите проект и нажмите кнопку в форме, чтобы проверить перегруженную ShowTax процедуру.
Читайте также: