Відповіді:
У Java всі нестатичні методи за замовчуванням є " віртуальними функціями ". Тільки методи, позначені ключовим словом остаточне , яке неможливо переоправити разом із приватними методами , які не успадковуються, є невіртуальними .
Так. Насправді всі методи екземпляра на Java за замовчуванням є віртуальними. Тільки певні методи не є віртуальними:
Ось кілька прикладів:
"Нормальні" віртуальні функції
Наступний приклад - зі старої версії сторінки вікіпедії, згаданої в іншій відповіді.
import java.util.*;
public class Animal
{
public void eat()
{
System.out.println("I eat like a generic Animal.");
}
public static void main(String[] args)
{
List<Animal> animals = new LinkedList<Animal>();
animals.add(new Animal());
animals.add(new Fish());
animals.add(new Goldfish());
animals.add(new OtherAnimal());
for (Animal currentAnimal : animals)
{
currentAnimal.eat();
}
}
}
class Fish extends Animal
{
@Override
public void eat()
{
System.out.println("I eat like a fish!");
}
}
class Goldfish extends Fish
{
@Override
public void eat()
{
System.out.println("I eat like a goldfish!");
}
}
class OtherAnimal extends Animal {}
Вихід:
Я їмо, як родова тварина. Я їмо, як риба! Я їмо, як золота рибка! Я їмо, як родова тварина.
Приклад з віртуальними функціями з інтерфейсами
Методи інтерфейсу Java - всі віртуальні. Вони повинні бути віртуальними, оскільки для забезпечення реалізації методів вони покладаються на класи реалізації. Код для виконання буде обраний лише під час виконання.
Наприклад:
interface Bicycle { //the function applyBrakes() is virtual because
void applyBrakes(); //functions in interfaces are designed to be
} //overridden.
class ACMEBicycle implements Bicycle {
public void applyBrakes(){ //Here we implement applyBrakes()
System.out.println("Brakes applied"); //function
}
}
Приклад з віртуальними функціями з абстрактними класами.
Подібно до інтерфейсів Анотаційні класи повинні містити віртуальні методи, оскільки вони покладаються на реалізацію класів, що розширюються. Наприклад:
abstract class Dog {
final void bark() { //bark() is not virtual because it is
System.out.println("woof"); //final and if you tried to override it
} //you would get a compile time error.
abstract void jump(); //jump() is a "pure" virtual function
}
class MyDog extends Dog{
void jump(){
System.out.println("boing"); //here jump() is being overridden
}
}
public class Runner {
public static void main(String[] args) {
Dog dog = new MyDog(); // Create a MyDog and assign to plain Dog variable
dog.jump(); // calling the virtual function.
// MyDog.jump() will be executed
// although the variable is just a plain Dog.
}
}
Усі функції на Java за замовчуванням є віртуальними.
Вам потрібно вийти зі свого шляху, щоб написати невіртуальні функції, додавши ключове слово «остаточне».
Це протилежне за замовчуванням C ++ / C #. Функції класу за замовчуванням є невіртуальними; ви робите їх так, додаючи "віртуальний" модифікатор.
Усі методи, які не є приватними екземплярами, за замовчуванням є Java.
У C ++ приватні методи можуть бути віртуальними. Це можна використати для ідіоми невіртуального інтерфейсу (NVI). У Java вам потрібно буде захистити методи перезапису NVI.
З специфікації мови Java, v3:
8.4.8.1 Переопределення (методами інстанцій) Метод екземпляра m1, оголошений у класі C, перекриває інший метод екземпляра, м2, оголошений у класі A, якщо все наступне є правдивим:
- С - підклас А.
- Підпис m1 - це підпис (§ 8.4.2) підпису m2.
- Або * m2 є загальнодоступним, захищеним або оголошеним з доступом за замовчуванням у тому ж пакеті, що і C, або * m1 перекриває метод m3, m3 відрізняється від m1, m3 відрізняється від m2, так що m3 перевищує м2.
У Java всі загальнодоступні (не приватні) змінні та функції за замовчуванням є Virtual . Більше того, змінні та функції, що використовують ключове слово final , не є віртуальними .