Java Language Polymorphism Virtual functions
Virtual Methods are methods in Java that are non-static and without the keyword Final in front. All methods by default are virtual in Java. Virtual Methods play important roles in Polymorphism because children classes in Java can override their parent classes’ methods if the function being overriden is non-static and has the same method signature.
There are, however, some methods that are not virtual. For example, if the method is declared private or with the keyword final, then the method is not Virtual.
Consider the following modified example of inheritance with Virtual Methods from this StackOverflow post How do virtual functions work in C# and Java? :
public class A < public void hello()< System.out.println("Hello"); >public void boo() < System.out.println("Say boo"); >> public class B extends A < public void hello()< System.out.println("No"); >public void boo() < System.out.println("Say haha"); >>
If we invoke class B and call hello() and boo(), we would get «No» and «Say haha» as the resulting output because B overrides the same methods from A. Even though the example above is almost exactly the same as method overriding, it is important to understand that the methods in class A are all, by default, Virtual.
Additionally, we can implement Virtual methods using the abstract keyword. Methods declared with the keyword «abstract» does not have a method definition, meaning the method’s body is not yet implemented. Consider the example from above again, except the boo() method is declared abstract:
public class A < public void hello()< System.out.println("Hello"); >abstract void boo(); > public class B extends A < public void hello()< System.out.println("No"); >public void boo() < System.out.println("Say haha"); >>
If we invoke boo() from B, the output will still be «Say haha» since B inherits the abstract method boo() and makes boo () output «Say haha».
Sources used and further readings:
Check out this great answer that gives a much more complete information about Virtual functions:
PDF — Download Java Language for free
Что такое виртуальная функция в Java?
Java – это объектно-ориентированный язык программирования, который поддерживает такие понятия, как полиморфизм, наследование, абстракция и т. д. Эти концепции ООП вращаются вокруг классов, объектов и функций-членов. Виртуальная функция в Java – одна из таких концепций, которая помогает в полиморфизме во время выполнения.
Что это такое?
Поведение виртуальной функции может быть переопределено наследующей функцией класса с тем же именем. Она в основном определяется в базовом классе и переопределяется в унаследованном классе.
Ожидается, что виртуальная функция будет определена в производном классе. Мы можем вызвать виртуальную функцию, ссылаясь на объект производного класса, используя ссылку или указатель базового класса.
Каждый нестатический метод по умолчанию является виртуальным методом. В Java нет виртуального ключевого слова, такого как C ++, но мы можем определить его и использовать для таких понятий, как полиморфизм во время выполнения.
Пример
class Vehicle < void make()< System.out.println("heavy duty"); >> public class Trucks extends Vehicle < void make()< System.out.println("Transport vehicle for heavy duty"); >public static void main(String args[]) < Vehicle ob1 = new Trucks(); ob1.make(); >>
Output: Transport vehicle for heavy duty
Каждый нестатический метод является виртуальной функцией, кроме финальных и закрытых методов. Методы, которые нельзя использовать для полиморфизма, не рассматриваются как виртуальные функции.
Статическая функция не считается виртуальной функцией, потому что статический метод связан с самим классом. Поэтому мы не можем вызвать статический метод из имени объекта или класса для полиморфизма. Даже когда мы переопределяем статический метод, он не резонирует с концепцией полиморфизма.
С интерфейсами
Все интерфейсы Java являются виртуальными, они полагаются на реализующие классы для обеспечения реализации методов. Код для выполнения выбирается во время выполнения. Вот простой пример для лучшего понимания.
interface Car < void applyBrakes(); >interface Audi implements Car < void applyBrakes()< System.out.println("breaks Applied"); >>
Здесь applyBreaks() является виртуальным, потому что функции в интерфейсах предназначены для переопределения.
Чистая
Чистая виртуальная функция – это виртуальная функция, для которой у нас нет реализаций. Абстрактный метод можно рассматривать как чисто виртуальную функцию. Давайте рассмотрим пример, чтобы лучше это понять.
abstract class Dog < final void bark()< System.out.println("woof"); >abstract void jump(); //this is a pure virtual function > class MyDog extends Dog < void jump()< System.out.println("Jumps in the air"); >> public class Runner < public static void main(String args[])< Dog ob1 = new MyDog(); ob1.jump(); >>
Полиморфизм
Полиморфизм во время выполнения – это когда вызов переопределенного метода разрешается во время выполнения, а не во время компиляции. Переопределенный метод вызывается через ссылочную переменную базового класса.
class Edureka < public void show()< System.out.println("welcome to edureka"); >> class Course extends Edureka < public void show()< System.out.println("Java Certification Program"); >public static void main(String args[]) < Edureka ob1 = new Course(); ob1.show(); >>
Output: Java Certification Course
Запомни
- Для виртуальной функции в Java вам не нужно явное объявление. Это любая функция, которая у нас есть в базовом классе и переопределена в производном классе с тем же именем.
- Указатель базового класса может использоваться для ссылки на объект производного класса.
- Во время выполнения программы указатель базового класса используется для вызова функций производного класса.
Указатели и виртуальные функции в Java
В настоящее время в Интернете можно найти множество статей как о перспективности платформы Java, так и об её ограниченности. Многих программистов, только присматривающихся к Яве, могут отпугнуть частые заявления, типа: «низкое быстродействие», «отсутствие указателей» и т.д.
На быстродействии я останавливаться не буду. По этой теме можно найти множество статей, например эту. В этой статье я попытаюсь развеять мнение, что в Java отсутствуют указатели. Да, они там действительно отсутствуют в том виде, в котором их можно увидеть в C/C++. Но не даром же все сложные типы в Java называются ссылочными. Можно рассмотреть пример на C. Эта программа меняет местами значения переменных x и y. Могут быть и другие ситуации, где результат должен возвращаться через параметры функции. Но это самый простейший, и, по-моему, самый доходчивый пример.
#include void change(int *a, int *b) int c=*a; *a=*b; *b=c; > int main() int x=2, y=3; printf("%d %d\n", x, y); change(&x, &y); printf("%d %d\n", x, y); return 0; >
Результат работы программы будет выглядеть следующим образом:
В 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. Хотя в данный момент его вполне можно назвать самодостаточным языком.