Antworten:
In Java sind alle nicht statischen Methoden standardmäßig " virtuelle Funktionen ". Nur Methoden, die mit dem Schlüsselwort final gekennzeichnet sind und nicht überschrieben werden können, sowie private Methoden , die nicht vererbt werden, sind nicht virtuell .
Ja. Tatsächlich sind alle Instanzmethoden in Java standardmäßig virtuell. Nur bestimmte Methoden sind nicht virtuell:
Hier sind einige Beispiele:
"Normale" virtuelle Funktionen
Das folgende Beispiel stammt aus einer alten Version der Wikipedia-Seite, die in einer anderen Antwort erwähnt wurde.
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 {}
Ausgabe:
Ich esse wie ein generisches Tier. Ich esse wie ein Fisch! Ich esse wie ein Goldfisch! Ich esse wie ein generisches Tier.
Beispiel mit virtuellen Funktionen mit Schnittstellen
Java- Schnittstellenmethoden sind alle virtuell. Sie müssen virtuell sein, da sie sich auf die implementierenden Klassen stützen, um die Methodenimplementierungen bereitzustellen. Der auszuführende Code wird nur zur Laufzeit ausgewählt.
Beispielsweise:
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
}
}
Beispiel mit virtuellen Funktionen mit abstrakten Klassen.
Ähnlich wie Schnittstellen Abstrakte Klassen müssen virtuelle Methoden enthalten , da sie die Umsetzung auf der Verlängerung Klassen verlassen. Beispielsweise:
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.
}
}
Alle Funktionen in Java sind standardmäßig virtuell.
Sie müssen sich alle Mühe geben, um nicht virtuelle Funktionen zu schreiben, indem Sie das Schlüsselwort "final" hinzufügen.
Dies ist das Gegenteil des C ++ / C # -Standards. Klassenfunktionen sind standardmäßig nicht virtuell. Sie machen sie so, indem Sie den Modifikator "virtuell" hinzufügen.
Alle nicht privaten Instanzmethoden sind in Java standardmäßig virtuell.
In C ++ können private Methoden virtuell sein. Dies kann für die NVI-Sprache (Non-Virtual-Interface) ausgenutzt werden. In Java müssen Sie die überschreibbaren NVI-Methoden schützen.
Aus der Java-Sprachspezifikation, Version 3:
8.4.8.1 Überschreiben (durch Instanzmethoden) Eine in einer Klasse C deklarierte Instanzmethode m1 überschreibt eine andere in Klasse A deklarierte Instanzmethode m2, wenn alle der folgenden Bedingungen erfüllt sind:
- C ist eine Unterklasse von A.
- Die Signatur von m1 ist eine Unterzeichnung (§8.4.2) der Signatur von m2.
- Entweder ist * m2 öffentlich, geschützt oder mit Standardzugriff im selben Paket wie C deklariert, oder * m1 überschreibt eine Methode m3, m3 verschieden von m1, m3 verschieden von m2, so dass m3 m2 überschreibt.
In Java sind alle öffentlichen (nicht privaten) Variablen und Funktionen standardmäßig virtuell . Darüber hinaus sind Variablen und Funktionen, die das Schlüsselwort final verwenden, nicht virtuell .