Respuestas:
En Java , todos los métodos no estáticos son por defecto " funciones virtuales " . Solo los métodos marcados con la palabra clave final , que no pueden anularse, junto con los métodos privados , que no se heredan, no son virtuales .
Si. De hecho, todos los métodos de instancia en Java son virtuales por defecto. Solo ciertos métodos no son virtuales:
Aquí hay unos ejemplos:
Funciones virtuales "normales"
El siguiente ejemplo es de una versión anterior de la página de Wikipedia mencionada en otra respuesta.
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 {}
Salida:
Como como un animal genérico. ¡Como como un pez! ¡Como como un pez dorado! Como como un animal genérico.
Ejemplo con funciones virtuales con interfaces
Los métodos de la interfaz Java son todos virtuales. Ellos deben ser virtual porque se basan en las clases que implementan para proporcionar las implementaciones de métodos. El código a ejecutar solo se seleccionará en tiempo de ejecución.
Por ejemplo:
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
}
}
Ejemplo con funciones virtuales con clases abstractas.
Similar a las interfaces Las clases abstractas deben contener métodos virtuales porque dependen de la implementación de las clases extendidas. Por ejemplo:
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.
}
}
Todas las funciones en Java son virtuales por defecto.
Debe hacer todo lo posible para escribir funciones no virtuales agregando la palabra clave "final".
Esto es lo opuesto al valor predeterminado de C ++ / C #. Las funciones de clase no son virtuales por defecto; los haces agregando el modificador "virtual".
Todos los métodos de instancias no privadas son virtuales por defecto en Java.
En C ++, los métodos privados pueden ser virtuales. Esto puede explotarse para el lenguaje de interfaz no virtual (NVI). En Java, necesitaría proteger los métodos anulables de NVI.
De la especificación del lenguaje Java, v3:
8.4.8.1 Anulación (por métodos de instancia) Un método de instancia m1 declarado en una clase C anula otro método de instancia, m2, declarado en la clase A si se cumple todo lo siguiente:
- C es una subclase de A.
- La firma de m1 es una sub firma (§8.4.2) de la firma de m2.
- * * M2 es público, está protegido o declarado con acceso predeterminado en el mismo paquete que C, o * m1 anula un método m3, m3 distinto de m1, m3 distinto de m2, de modo que m3 anula m2.
En Java, todas las variables y funciones públicas (no privadas) son virtuales de forma predeterminada. Además, las variables y funciones que usan la palabra clave final no son virtuales .