180 votes

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

Est-il possible d'écrire virtuel en Java, comme on le ferait en C++ ?

Ou existe-t-il une approche Java appropriée que vous pouvez mettre en œuvre et qui produit un comportement similaire ? Pourrais-je avoir des exemples ?

328voto

Klaus Byskov Pedersen Points 43779

De wikipedia

En Java toutes les méthodes non statiques sont par par défaut " les fonctions virtuelles. " Seulement marquées par le symbole mot-clé final , qui ne peut pas être remplacée, ainsi que w méthodes privées , héritées, sont non virtuel .

4 votes

Ici est l'un des Jon Skeet La réponse de l'auteur de l'article est la suivante.

0 votes

Je me suis demandé si c'était vraiment vrai, car d'après ce que j'ai lu, en Java, la distribution dynamique des méthodes n'a lieu que pour l'objet sur lequel la méthode est appelée - comme cela a été expliqué aquí Ainsi, l'exemple expliquant les fonctions virtuelles en C++ aquí n'est pas valable pour Java.

0 votes

@QuaziIrfan C'est la différence entre Java et C#.

102voto

Eric Leschinski Points 14289

Peut-on é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 :

  • les méthodes de la classe (parce qu'en général, chaque instance contient des informations sur ses méthodes spécifiques, comme un pointeur sur une table virtuelle, mais aucune instance n'est disponible ici).
  • Méthodes d'instance privées (parce qu'aucune autre classe ne peut accéder à la méthode, l'instance appelante a toujours le type de la classe qui la définit et est donc connue sans ambiguïté au moment de la compilation).

Voici quelques exemples :

"Fonctions virtuelles "normales

L'exemple suivant provient d'un 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 :

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

Exemple de fonctions virtuelles avec interfaces

Java méthodes de l'interface sont tous virtuels. Ils sont doit sont virtuelles parce qu'elles dépendent des classes d'implémentation pour fournir les implémentations des 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 de fonctions virtuelles avec des classes abstraites.

Similaire aux interfaces Classes abstraites doit contiennent des méthodes virtuelles parce qu'elles dépendent de 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.
    }
}

1 votes

Il s'agit de la réponse la plus complète. Elle fournit deux façons d'implémenter une fonction virtuelle puisque java n'a pas de mot-clé. Je vous remercie.

0 votes

Réponse bien meilleure que la citation de Wikipédia. Venant du c++ et étant paresseux dans mes études de Java, l'abstrait était ce que je cherchais.

0 votes

@David En quoi cette réponse est-elle meilleure ? La citation de wikipedia est complète, concise et correcte. Cette réponse, en revanche, ne mentionne pas l'éléphant dans la pièce : Par défaut tous en Java (sauf exceptions listées dans l'article de wikipedia) sont virtuelles. Ni les classes abstraites ni les interfaces ne sont nécessaires pour les fonctions virtuelles, ce qui ne fait qu'ajouter un bruit trompeur. Et puis cela "exige de grandes compétences en matière de communication et une maîtrise approfondie des principes sous-jacents"... bon sang. Il s'agit là d'une affirmation auto-falsifiante : Personne qui possède ces compétences ne gaspillerait de l'espace disque précieux avec elles.

57voto

duffymo Points 188155

En Java, toutes les fonctions sont virtuelles par défaut.

Vous devez vous efforcer d'écrire des fonctions non virtuelles en ajoutant le mot-clé "final".

C'est l'inverse de la valeur par défaut de C++/C#. Les fonctions de classe ne sont pas virtuelles par défaut ; vous les rendez virtuelles en ajoutant le modificateur "virtual".

5 votes

Les fonctions privées, comme indiqué dans la réponse de Klaus, sont également non virtuelles.

9voto

Andy Thomas Points 30979

Tous non privé Les méthodes d'instance sont virtuelles par défaut en Java.

En C++, les méthodes privées peuvent être virtuelles. Cela peut être exploité pour l'idiome de l'interface non virtuelle (NVI). En Java, vous devez protéger les méthodes NVI qui peuvent être surchargées.

Extrait de la spécification du langage Java, v3 :

8.4.8.1 Surcharge (par les méthodes d'instance) Une méthode d'instance m1 déclarée dans une classe C surcharge une autre méthode d'instance, m2, déclarée dans la classe A si toutes les conditions suivantes sont vraies :

  1. C est une sous-classe de A.
  2. La signature de m1 est une sous-signature (§8.4 de m2.
  3. E * m2 est public, protégé ou déclaré avec un accès par défaut dans le même paquetage que C, soit * m1 surcharge une méthode m3, m3 distincte m2, telle que m3 remplace m2.

4voto

RepDetec Points 306

Oui, il est possible d'écrire des "fonctions" virtuelles en Java.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X