Odpowiedzi:
W Javie wszystkie metody niestatyczne są domyślnie „ funkcjami wirtualnymi ” . Tylko metody oznaczone słowem kluczowym final , których nie można przesłonić, oraz metody prywatne , które nie są dziedziczone, są niewirtualne .
Tak. W rzeczywistości wszystkie metody instancji w Javie są domyślnie wirtualne. Tylko niektóre metody nie są wirtualne:
Oto kilka przykładów:
„Normalne” funkcje wirtualne
Poniższy przykład pochodzi ze starej wersji strony wikipedii, o której mowa w innej odpowiedzi.
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 {}
Wynik:
Jem jak zwykłe zwierzę. Jem jak ryba! Jem jak złota rybka! Jem jak zwykłe zwierzę.
Przykład z funkcjami wirtualnymi z interfejsami
Wszystkie metody interfejsu Java są wirtualne. Oni muszą być wirtualny, ponieważ opierają się one na zajęciach wykonawczych w celu zapewnienia implementacje metod. Kod do wykonania zostanie wybrany tylko w czasie wykonywania.
Na przykład:
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
}
}
Przykład z funkcjami wirtualnymi z klasami abstrakcyjnymi.
Podobnie jak w przypadku interfejsów Klasy abstrakcyjne muszą zawierać metody wirtualne, ponieważ opierają się na implementacji klas rozszerzających. Na przykład:
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.
}
}
Wszystkie funkcje w Javie są domyślnie wirtualne.
Aby napisać funkcje niewirtualne, musisz zrobić wszystko, co w twojej mocy, dodając słowo kluczowe „final”.
Jest to przeciwieństwo domyślnego C ++ / C #. Funkcje klas są domyślnie niewirtualne; robisz je tak, dodając modyfikator „wirtualny”.
Wszystkie non-prywatne metody instancji są wirtualne domyślnie w Javie.
W C ++ metody prywatne mogą być wirtualne. Można to wykorzystać w przypadku idiomu interfejsu niewirtualnego (NVI). W Javie należałoby zabezpieczyć metody zastępowania NVI.
Ze specyfikacji języka Java, wersja 3:
8.4.8.1 Przesłanianie (przez metody instancji) Metoda instancji m1 zadeklarowana w klasie C przesłania inną metodę instancji m2, zadeklarowaną w klasie A iff, wszystkie poniższe są prawdziwe:
- C jest podklasą A.
- Podpis m1 jest podpisem (§ 8.4.2) podpisu m2.
- Albo * m2 jest publiczny, chroniony lub zadeklarowany z domyślnym dostępem w tym samym pakiecie co C, albo * m1 zastępuje metodę m3, m3 różną od m1, m3 różną od m2, tak że m3 zastępuje m2.
W Javie wszystkie publiczne (nieprywatne) zmienne i funkcje są domyślnie wirtualne . Ponadto zmienne i funkcje używające słowa kluczowego final nie są wirtualne .