¿Puedes escribir funciones / métodos virtuales en Java?


¿Es posible escribir métodos virtuales en Java, como se haría en C++?

O, ¿hay un enfoque Java adecuado que se puede implementar que produce un comportamiento similar? ¿Podría darme algunos ejemplos?

Author: Eric Leschinski, 2010-12-28

6 answers

De wikipedia

En Java , todos los métodos no estáticos son por defecto " funciones virtuales. " Solamente métodos marcados con la palabra clave final, que no puede ser anulado, junto con métodos privados, que no son heredados, son no virtuales.

 255
Author: Klaus Byskov Pedersen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-10 18:29:30

¿ Se pueden escribir funciones virtuales en Java?

Sí. De hecho, todos los métodos de instancia en Java son virtuales por defecto. Solo ciertos métodos no son virtuales:

  • Métodos de clase (porque típicamente cada instancia contiene información como un puntero a una vtable sobre sus métodos específicos, pero ninguna instancia está disponible aquí).
  • Métodos de instancia privada (debido a que ninguna otra clase puede acceder al método, la instancia invocadora siempre tiene el tipo de la clase definidora y es por lo tanto unambiguously conocido en tiempo de compilación).

Aquí hay algunos ejemplos:

"Funciones virtuales normales

El siguiente ejemplo proviene de una versión antigua 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:

I eat like a generic Animal.
I eat like a fish!
I eat like a goldfish!
I eat like a generic Animal.

Ejemplo con interfaces

Java Los métodos de interfaz son todos virtuales. They must be virtual because they rely on the implementing classes to provide las implementaciones del método. 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 interfaces Clases abstractas debe contener métodos virtuales porque dependen de la implementación de las clases extendedoras. 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.
    }
}
 84
Author: Eric Leschinski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-05 17:19:47

Todas las funciones en Java son virtuales por defecto.

Tienes que hacer todo lo posible para escribir funciones no virtuales añadiendo la palabra clave "final".

Esto es lo contrario del valor predeterminado de C++/C#. Las funciones de clase no son virtuales por defecto; usted las hace así agregando el modificador" virtual".

 54
Author: duffymo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-28 16:18:23

Todos los métodos de instancia no privados son virtuales por defecto en Java.

En C++, los métodos privados pueden ser virtuales. Esto puede ser explotado para el lenguaje no-virtual-interface (NVI). En Java, necesitarías proteger los métodos anulables de NVI.

De la Especificación del lenguaje Java, v3:

8.4.8.1 Sobreescribir (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 clase A iff todos de los siguientes son verdaderas:

  1. C es una subclase de A.
  2. La firma de m1 es una subsignatura (§8.4.2) de la firma de m2.
  3. O bien * m2 es público, protegido o declarado con acceso predeterminado en el el mismo paquete que C, o * m1 anula un método m3, m3 distinto de m1, m3 distinto de m2, tal que m3 anula a m2.
 9
Author: Andy Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-10 19:32:32

Sí, puede escribir "funciones" virtuales en Java.

 2
Author: RepDetec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-28 16:42:23

En Java, todas las variables y funciones públicas (no privadas) son Virtuales por defecto. Además las variables y funciones que usan keyword finalno son virtuales.

 0
Author: Parvej Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-25 00:53:13