web-dev-qa-db-fra.com

Pouvez-vous écrire des fonctions/méthodes virtuelles en Java?

Est-il possible d'écrire des méthodes virtual en Java, comme on le ferait en C++?

Ou bien, existe-t-il une approche Java appropriée que vous pouvez implémenter qui produit un comportement similaire? Puis-je avoir quelques exemples s'il vous plaît?

139
yonatan

De wikipedia

Dans Java, toutes les méthodes non statiques sont par valeur par défaut "fonctions virtuelles." uniquement méthodes marquées avec le mot-clé final, qui ne peut pas être ignoré, avec méthodes privées, qui ne sont pas héritées, sont non-virtuelles.

262

Pouvez-vous écrire des fonctions virtuelles en Java?

Oui. En fait, toutes les méthodes d'instance en Java sont virtuelles par défaut. Seules certaines méthodes ne sont pas virtuelles:

  • Méthodes de classe (car chaque instance contient généralement des informations comme un pointeur sur une vtable sur ses méthodes spécifiques, mais aucune instance n'est disponible ici).
  • Méthodes d'instance privées (aucune autre classe ne pouvant accéder à la méthode, l'instance appelante a toujours le type de la classe de définition elle-même et est donc connue sans ambiguïté au moment de la compilation).

Voici quelques exemples:

"Fonctions normales" virtuelles

L'exemple suivant provient d'une ancienne version de la page wikipedia mentionnée dans une autre réponse.

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 {}

Sortie:

 Je mange comme un animal générique ... je mange comme un poisson! 
 Je mange comme un poisson rouge! 
 Je mange comme un animal générique ...

Exemple avec avec interfaces 

Java méthodes d'interface sont tous virtuels. Ils doivent être virtuels car ils s'appuient sur les classes d'implémentation pour fournir les implémentations de méthodes. Le code à exécuter ne sera sélectionné qu'au moment de l'exécution.

Par exemple:

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
    }
}

Exemple avec des fonctions virtuelles avec des classes abstraites. 

Similaire aux interfaces classes abstraites } _ doit contenir des méthodes virtuelles car elles reposent sur l'implémentation des classes d'extension. Par exemple:

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.
    }
}
86
Eric Leschinski

Toutes les fonctions en Java sont virtuelles par défaut.

Vous devez faire tout votre possible pour écrire des fonctions non virtuelles en ajoutant le mot clé "final".

C'est le contraire de la valeur par défaut C++/C #. Les fonctions de classe ne sont pas virtuelles par défaut. vous le faites en ajoutant le modificateur "virtuel".

54
duffymo

Toutes les méthodes non-private instance sont virtuelles par défaut en Java. 

En C++, les méthodes privées peuvent être virtuelles. Cela pourrait être exploité par l'idiome NVI. En Java, vous devez protéger les méthodes pouvant être surchargées par NVI.

A partir de la spécification du langage Java, v3:

8.4.8.1 Remplacement (par les méthodes d'instance) Une méthode d'instance m1 déclaré dans une classe C annule une autre méthode d'instance, m2, a déclaré en classe A ssi toutes les caractéristiques suivantes sont vrai:

  1. C est une sous-classe de A.
  2. La signature de m1 est une sous-signature (§8.4.2) de la signature de m2.
  3. Non plus * m2 est public, protégé ou déclaré avec un accès par défaut dans le fichier même paquet que C, ou * m1 remplace une méthode m3, m3 distinct de m1, m3 distinct de m2, de sorte que m3 remplace m2.
9
Andy Thomas

Oui, vous pouvez écrire des "fonctions" virtuelles en Java.

2
RepDetec

En Java, toutes les variables et fonctions publiques (non privées) sont Virtual par défaut. De plus, les variables et les fonctions utilisant le mot-clé final ne sont pas virtuel .

0
Parvej Ahmed