Le polymorphisme consituant un concept majeur de la programmation orientée objet, la surcharge (overload) des méthodes est l'une des représentantes de cette particularité dans le langage Java.

Si deux méthodes possédent un nom semblable mais différentes signatures, le nom de ces méthodes est dit surchargé.

Chaque méthode se distingue par une signature spécifique, c'est-à-dire :

  • le nom,
  • le type des paramètres,
  • la séquence de ces derniers.
modif type_retour nom(type param, ..., type paramN)
{ ... }
int calculer(float somme, int pourcentage)
{ ... }

Le type de retour ne fait pas partie de la signature d'une méthode car lors de l'appel d'une méthode, rien ne suggère au compilateur quel est le type de retour attendu.

class UneClasse {
  public int uneMethode(int un_parametre){
    // Bloc d'instructions...
  }
  public long uneMethode(int un_parametre){
    // Bloc d'instructions...
  }
}
...
UneClasse obj = new UneClasse();
System.out.println(obj.uneMethode(100));
// Quelle méthode est attendue ?
// De plus, une erreur se produit lors de la
// compilation de la classe UneClasse.

Il n'existe aucune contrainte à propos des types de retour à condition que les méthodes aient des signatures strictement différentes, sinon le compilateur générera une erreur.

Les clauses d'exceptions throws des deux méthodes surchargées n'ont aucune incidence sur la validité de la surcharge.

Les méthodes peuvent être déclarées dans une même classe ou provenir de l'héritage d'une superclasse, ou l'une est déclarée dans une classe et l'autre héritée d'une superclasse.

Ainsi dans une classe ou dans une hiérarchie de classes, plusieurs méthodes peuvent posséder un nom identique si leurs paramètres sont différents.
Si des méthodes possèdent des paramètres identiques mais sont déclarées dans des classes distinctes, les méthodes sont dites outrepassées (voir L'outrepassement des méthodes).

void calcul()
{ // instructions... }

void calcul(int valeur, int autre_valeur)
{ // instructions... }

void calcul(float valeur, int autre_valeur)
{ // instructions... }

// Appels des méthodes
operation.calcul();

operation.calcul(100);

operation.calcul(12.3, 4);

Les méthodes surchargées peuvent avoir un type de retour et des modificateurs distincts à condition que leurs paramètres soient différents.

void calcul()
{ // instructions... }

public int calcul(int parametre)
{ // instructions... }

protected double calcul(int argument, double autre_argument)
{ // instructions... }

Toutefois, deux méthodes ne peuvent avoir un nom et des paramètres identiques avec un type de retour différent. Dans ce cas, le compilateur Java générera une erreur.

int calcul(int parametre)
{ // instructions... }

double calcul(int parametre)
{ // instructions... }
// Ceci entrainerait une erreur de compilation !

Dans sa propre classe, une méthode privée peut être surchargée sans problème. De même, une méthode de même nom peut être créée dans une classe héritée sans provoquer d'erreur de compilation ou d'exécution.

class Prog {
  static String l_argument = "";
  static char caracteres[];
  public static void main(String[] args){
    if(args.length > 0)
      for(int i = 0; i < args.length; i++)
        l_argument += args[i] + " ";
    else
        l_argument = "Les arguments sur la ligne de commande !";
    caracteres = l_argument.toCharArray();
    UneClasse ref_obj = new UneClasse();
    ref_obj.uneMethode(l_argument);
    ref_obj.setMethodeCl(caracteres[0]);
    // erreur de compilation due à un
// appel directe d'une méthode privée
ref_obj.uneMethode(caracteres[0]); } } class SuperClasse { private void uneMethode(String un_parametre){ System.out.println("Methode privee(SuperClasse) : " + un_parametre); } private void uneMethode(char un_parametre){ System.out.println("Methode privee(SuperClasse) : " + un_parametre); } public void setMethodeS1(String param){ uneMethode(param); } public void setMethodeS2(char param){ uneMethode(param); } } class UneClasse extends SuperClasse { public void uneMethode(String un_parametre){ System.out.println("Methode privee(UneClasse) : " + un_parametre); super.setMethodeS1(un_parametre); } private void uneMethode(char un_parametre){ System.out.println("Methode publique(UneClasse) : " + un_parametre); super.setMethodeS2(un_parametre); } public void setMethodeCl(char un_parametre){ uneMethode(un_parametre); } }

D'ailleurs, les méthodes statiques peuvent également être surchargées sans aucune contrainte.

La surcharge des méthodes s'applique de la même façon aux constructeurs. Ainsi, il devient possible à une classe de posséder plusieurs constructeurs permettant de paramétrer différemment un objet lors de sa création.

class Article {
  int idProduit;
  float prix = 0.0f;
  float reduction = 0.0f;

  Article(int idProduit, float prix, float reduction) {
    this.idProduit = idProduit;
    this.prix = prix;
    this.reduction = reduction;
  }
  Article(int idProduit) {
    this.idProduit = idProduit;
  }
}

Dans le cas des constructeurs, il n'existe pas de type de retour. Donc, la surcharge ne tient compte que du nom et des paramètres de ce genre particulier de méthodes.