Что такое виртуальная функция и используются ли они в java

Что такое виртуальная функция в Java?

Java – это объектно-ориентированный язык программирования, который поддерживает такие понятия, как полиморфизм, наследование, абстракция и т. д. Эти концепции ООП вращаются вокруг классов, объектов и функций-членов. Виртуальная функция в Java – одна из таких концепций, которая помогает в полиморфизме во время выполнения.

Что это такое?

Поведение виртуальной функции может быть переопределено наследующей функцией класса с тем же именем. Она в основном определяется в базовом классе и переопределяется в унаследованном классе.

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

Каждый нестатический метод по умолчанию является виртуальным методом. В Java нет виртуального ключевого слова, такого как C ++, но мы можем определить его и использовать для таких понятий, как полиморфизм во время выполнения.

Пример

Каждый нестатический метод является виртуальной функцией, кроме финальных и закрытых методов. Методы, которые нельзя использовать для полиморфизма, не рассматриваются как виртуальные функции.

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

С интерфейсами

Все интерфейсы Java являются виртуальными, они полагаются на реализующие классы для обеспечения реализации методов. Код для выполнения выбирается во время выполнения. Вот простой пример для лучшего понимания.

Здесь applyBreaks() является виртуальным, потому что функции в интерфейсах предназначены для переопределения.

Чистая

Чистая виртуальная функция – это виртуальная функция, для которой у нас нет реализаций. Абстрактный метод можно рассматривать как чисто виртуальную функцию. Давайте рассмотрим пример, чтобы лучше это понять.

Полиморфизм

Полиморфизм во время выполнения – это когда вызов переопределенного метода разрешается во время выполнения, а не во время компиляции. Переопределенный метод вызывается через ссылочную переменную базового класса.

Источник

Как работают виртуальные функции в C # и Java?

Как виртуальные функции работают на С# и Java?

Использует ли он такую ​​же концепцию vtable и vpointer, что и для С++, или это нечто совершенно другое?

6 ответов

Как виртуальные функции работают в Java?

Кодирующие интервьюеры любят этот вопрос. Да. Хотя Java не имеет виртуального ключевого слова, Java имеет виртуальные функции, и вы можете их записать.

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

Направьте интервьюера на конкретный пример виртуальной функции.

Да, вы можете писать виртуальные функции в Java с интерфейсами.

Да, вы можете писать виртуальные функции в Java с абстрактными классами.

Java Абстрактные классы содержат неявно «виртуальные» методы, реализуемые классами, расширяющими его. Например:

Вы можете заставить функцию НЕ быть виртуальной в родовом классе, сделав ее final

В Java нет виртуального ключевого слова.

Он просто решает самую производную версию любого метода, который вы вызываете.

В ответ на ваш комментарий, Naveen:

Если вы сказали A a = new A(); a.sayhi(); он будет печатать «A».

Терминология java является динамической. Вы можете считать это виртуальным, но это может смутить некоторых разработчиков Java. те, кто не знает С++, по крайней мере. В Java нет явных указателей, поэтому нам не нужно беспокоиться о виртуальном/не виртуальном. Нет VTables, вы просто возвращаетесь к классу и его предкам, пока не найдете реализацию метода, который вы хотите. Там только одно наследование, поэтому вам не нужно беспокоиться о порядке конструкторов (он всегда снизу вверх).

В С++ вы получаете другое поведение, если у вас есть виртуальные методы и что-то вроде

где a было A *, указывающим на экземпляр B вместо

Источник

Указатели и виртуальные функции в Java

В настоящее время в Интернете можно найти множество статей как о перспективности платформы Java, так и об её ограниченности. Многих программистов, только присматривающихся к Яве, могут отпугнуть частые заявления, типа: «низкое быстродействие», «отсутствие указателей» и т.д.

На быстродействии я останавливаться не буду. По этой теме можно найти множество статей, например эту. В этой статье я попытаюсь развеять мнение, что в Java отсутствуют указатели. Да, они там действительно отсутствуют в том виде, в котором их можно увидеть в C/C++. Но не даром же все сложные типы в Java называются ссылочными. Можно рассмотреть пример на C. Эта программа меняет местами значения переменных x и y. Могут быть и другие ситуации, где результат должен возвращаться через параметры функции. Но это самый простейший, и, по-моему, самый доходчивый пример.

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

В Java с простыми типами нельзя сделать это же самое. Но кто нам мешает написать класс-оболочку для простого типа? В общем, рассмотрим аналогичный пример на Java.

Сначала опишем класс-оболочку для типа int:

public class IntPtr <
public int value;

public IntPtr ( int a ) <
value = a;
>
>

Затем, используем этот класс в программе:

public class Main <
public void change ( IntPtr x, IntPtr y ) <
int z = x.value;
x.value = y.value;
y.value = z;
>

public static void main ( String [] args ) <
Main m = new Main () ;
IntPtr a = new IntPtr ( 2 ) ;
IntPtr b = new IntPtr ( 3 ) ;
System.out.print ( a.value ) ;
System.out.print ( ‘ ‘ ) ;
System.out.println ( b.value ) ;
m.change ( a, b ) ;
System.out.print ( a.value ) ;
System.out.print ( ‘ ‘ ) ;
System.out.println ( b.value ) ;
>
>

Результат будет таким же:

Недостатком использования такого вида «указателей» может быть только «лишняя писанина», которой нет в С. Но при наличии таких сред, как NetBeans или Eclipse (и некоторых коммерческих), с их развитыми суфлёрами кода, я думаю, наличие «лишнего» кода не является серьёзной проблемой.

Далее можно отметить наличие в Яве только виртуальных функций. При этом не нужно писать перед функцией слово virtual. Да его и нет в языке. Рассмотрим пример:

package virtualfunctest;
//суперкласс
public class Parent <
protected void f1 () <
System.out.println ( «Parent class» ) ;
>
public void f2 () <
f1 () ;
>
>

package virtualfunctest;
// производный класс
public class Child extends Parent <
protected void f1 () <
System.out.println ( «Child class» ) ;
>
>

// использование функций
package virtualfunctest;

public class Main <
public static void main ( String [] args ) <
Parent obj;
obj= new Parent () ;
obj.f2 () ;
obj= new Child () ;
obj.f2 () ;
>
>

Таким образом, можно увидеть, что язык Java всё же имеет указатели (об этом, кстати, разработчики из Sun Microsystems неоднократно говорили). Главное – это подход к ним. Я не думаю, что в этой статье я показал что-то новое людям, уже работавшим с этим языком. Но думаю, что для новичков эта статься будет хоть чем-то полезна.

А вообще, всё, чего не хватает в языке Ява можно реализовать с помощью JNI. Хотя в данный момент его вполне можно назвать самодостаточным языком.

Источник

Как полиморфизм реализован внутри JVM

Перевод данной статьи подготовлен специально для студентов курса «Разработчик Java».

Что такое виртуальная функция и используются ли они в java. Смотреть фото Что такое виртуальная функция и используются ли они в java. Смотреть картинку Что такое виртуальная функция и используются ли они в java. Картинка про Что такое виртуальная функция и используются ли они в java. Фото Что такое виртуальная функция и используются ли они в java

В моей предыдущей статье Everything About Method Overloading vs Method Overriding (“Все о перегрузке и переопределении методов”) были рассмотрены правила и различия перегрузки и переопределения методов. В этой статье мы посмотрим, как обрабатывается перегрузка и переопределение методов внутри JVM.

Для примера возьмем классы из предыдущей статьи: родительский Mammal (млекопитающее) и дочерний Human (человек).

На вопрос о полиморфизме мы можем посмотреть с двух сторон: с “логической” и “физической”. Давайте сначала рассмотрим логическую сторону вопроса.

Логическая точка зрения

С логической точки зрения, на этапе компиляции вызываемый метод рассматривается как относящийся к типу ссылки. Но во время выполнения будет вызываться метод объекта, на который указывает ссылка.

Это все довольно просто, пока мы остаемся на концептуальном уровне. Но как же JVM обрабатывает это все внутри? Как JVM вычисляет, какой метод должен быть вызван?

Также мы знаем, что перегруженные методы (overload) не называются полиморфными и резолвятся во время компиляции. Хотя иногда перегрузку методов называют полиморфизмом времени компиляции или ранним/статическим связыванием.

Переопределенные методы (override) резолвятся во время выполнения, так как компилятор не знает, есть ли переопределенные методы в объекте, который присваивается ссылке.

Физическая точка зрения

Команда выше покажет две секции байткода.

1. Пул констант. Содержит почти все, что необходимо для выполнения программы. Например, ссылки на методы ( #Methodref ), классы ( #Class ), литералы строк ( #String ).

Что такое виртуальная функция и используются ли они в java. Смотреть фото Что такое виртуальная функция и используются ли они в java. Смотреть картинку Что такое виртуальная функция и используются ли они в java. Картинка про Что такое виртуальная функция и используются ли они в java. Фото Что такое виртуальная функция и используются ли они в java

2. Байткод программы. Выполняемые инструкции байткода.

Что такое виртуальная функция и используются ли они в java. Смотреть фото Что такое виртуальная функция и используются ли они в java. Смотреть картинку Что такое виртуальная функция и используются ли они в java. Картинка про Что такое виртуальная функция и используются ли они в java. Фото Что такое виртуальная функция и используются ли они в java

Почему перегрузка методов называется статическим связыванием

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

Почему переопределение методов называется динамическим связыванием

Для вызова методов anyMammal.speak() и humanMammal.speak() байткод одинаковый, так как с точки зрения компилятора оба метода вызываются для класса Mammal :

Итак, теперь возникает вопрос, если у обоих вызовов одинаковый байткод, как JVM узнает, какой метод вызвать?

Инструкция invokevirtual вызывает метод экземпляра через диспетчеризацию по (виртуальному) типу объекта. Это нормальная диспетчеризация методов в языке программирования Java.

JVM использует инструкцию invokevirtual для вызова в Java методов, эквивалентных виртуальным методам C++. В C++ для переопределения метода в другом классе, метод должен быть объявлен как виртуальный (virtual). Но в Java по умолчанию все методы виртуальные (кроме final и static методов), поэтому в дочернем классе мы можем переопределить любой метод.

Инструкция invokevirtual принимает указатель на метод, который нужно вызвать ( #4 — индекс в пуле констант).

Но ссылка #4 ссылается дальше на другой метод и Class.

Все эти ссылки используются совместно для получения ссылки на метод и класс, в котором находится нужный метод. Это также упоминается в спецификации JVM (прим. переводчика: ссылка на JVM spec 2.7):

Java Virtual Machine не требует какой-либо определённой внутренней структуры объектов.

В некоторых реализациях Java Virtual Machine, выполненных компанией Oracle, ссылка на экземпляр класса представляет собой ссылку на обработчик, который сам по себе состоит из пары ссылок: одна указывает на таблицу методов объекта и указатель на объект Class, представляющий тип объекта, а другая на область данных в куче, содержащую данные объекта.

Это означает, что каждая ссылочная переменная содержит два скрытых указателя:

Из приведенных выше рассуждений можно сделать вывод, что ссылка на объект косвенно содержит ссылку/указатель на таблицу, которая содержит все ссылки на методы этого объекта. Java позаимствовала эту концепцию из C ++. Эта таблица известна под различными именами, такими как таблица виртуальных методов (VMT), таблица виртуальных функций (vftable), виртуальная таблица (vtable), таблица диспетчеризации.

Мы не можем быть уверены в том, как vtable реализован в Java, потому что это зависит от конкретной JVM. Но мы можем ожидать, что стратегия будет примерно такая же, как и в C ++, где vtable — это структура, похожая на массив, которая содержит имена методов и их ссылки. Всякий раз, когда JVM пытается выполнить виртуальный метод, она запрашивает его адрес в vtable.

Для каждого класса существует только одна vtable, это означает, что таблица уникальна и одинакова для всех объектов класса, аналогично объекту Class. Объекты Class подробнее рассмотрены в статьях Why an outer Java class can’t be static и Why Java is Purely Object-Oriented Language Or Why Not.

Что такое виртуальная функция и используются ли они в java. Смотреть фото Что такое виртуальная функция и используются ли они в java. Смотреть картинку Что такое виртуальная функция и используются ли они в java. Картинка про Что такое виртуальная функция и используются ли они в java. Фото Что такое виртуальная функция и используются ли они в java

Что такое виртуальная функция и используются ли они в java. Смотреть фото Что такое виртуальная функция и используются ли они в java. Смотреть картинку Что такое виртуальная функция и используются ли они в java. Картинка про Что такое виртуальная функция и используются ли они в java. Фото Что такое виртуальная функция и используются ли они в java

Что такое виртуальная функция и используются ли они в java. Смотреть фото Что такое виртуальная функция и используются ли они в java. Смотреть картинку Что такое виртуальная функция и используются ли они в java. Картинка про Что такое виртуальная функция и используются ли они в java. Фото Что такое виртуальная функция и используются ли они в java

Инструкция invokevirtual заставляет JVM обрабатывать значение в ссылке на метод # 4 не как адрес, а как имя метода, которое нужно искать в vtable для текущего объекта.
Я надеюсь, теперь стало более понятно то, как JVM использует пул констант и таблицу виртуальных методов для определения того, какой метод вызывать.
Код примера вы можете найти в репозитории Github.

Источник

Можете ли вы написать виртуальные функции / методы на Java?

можно писать виртуальный методы в Java, как это было бы в C++?

или, есть ли правильный подход Java, который вы можете реализовать, который производит подобное поведение? Могу я привести несколько примеров?

6 ответов

с Википедия

на Java, все нестатические методы по по умолчанию «виртуальные функции.» только методы, отмеченные ключевое слово final, который нельзя отменить, вместе с частные методы, которые не в наследство, являются non-virtual.

можете ли вы писать виртуальные функции на Java?

да. Фактически, все методы экземпляра в Java являются виртуальными по умолчанию. Только некоторые методы не являются виртуальными:

вот несколько примеров:

«нормальные» виртуальные функции

следующий пример из старая версия страницы Википедии, упомянутой в другом ответе.

пример с интерфейсами

Java методы интерфейса все виртуальный. Они!—33—>должны быть виртуальными, потому что они полагаются на классы реализации для предоставления реализаций метода. Код для выполнения будет выбран только во время выполнения.

пример с виртуальными функциями с абстрактными классами.

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

все функции в Java являются виртуальными по умолчанию.

вы должны сделать все возможное, чтобы написать не виртуальные функции, добавив ключевое слово «final».

Это противоположность C++/C# по умолчанию. По умолчанию функции класса не являются виртуальными; вы делаете их так, добавляя модификатор «virtual».

все non-private методы экземпляра являются виртуальными по умолчанию в Java.

В C++, частные методы могут быть виртуальными. Это можно использовать для идиомы non-virtual-interface (NVI). В Java вам нужно будет защитить переопределяемые методы NVI.

из спецификации языка Java, v3:

8.4.8.1 переопределение (методами экземпляра) метода экземпляра m1 объявленные в классе C может другой метод экземпляра, м2, объявленный в классе A iff все следующие верны:

Да, вы можете писать виртуальные «функции» на Java.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *