Utilisation du mot-clé final avec héritage en Java

Alors que l'un des Java's forces est le concept d'héritage, dans lequel on classe peut dériver d'une autre, il est parfois souhaitable d'empêcher l'héritage par une autre classe. Pour éviter l'héritage, utilisez le mot clé "final" lors de la création de la classe.

Par exemple, si une classe est susceptible d'être utilisée par d'autres programmeurs, vous souhaiterez peut-être empêcher l'héritage si des sous-classes créées peuvent causer des problèmes. Un exemple typique est le Classe de chaîne. Si nous voulions créer une sous-classe String:

public class MyString étend String {
}

Nous serions confrontés à cette erreur:

 ne peut pas hériter de java.lang final. Chaîne 

Les concepteurs de la classe String ont réalisé qu'elle n'était pas candidate à l'héritage et ont empêché son extension.

Pourquoi empêcher l'héritage?

La principale raison d'empêcher héritage est de s'assurer que le comportement d'une classe n'est pas corrompu par une sous-classe.

Supposons que nous ayons un compte de classe et une sous-classe qui le prolonge, OverdraftAccount. Le compte de classe a une méthode getBalance ():

instagram viewer
 public double getBalance ()

{

 retourner this.balance;

 } 

À ce stade de notre discussion, la sous-classe OverdraftAccount n'a pas remplacé cette méthode.

(Remarque: Pour une autre discussion sur l'utilisation de ces classes Account et OverdraftAccount, voyez comment un la sous-classe peut être traitée comme une superclasse).

Créons une instance pour chacune des classes Account et OverdraftAccount:

 Compte bobsAccount = nouveau compte (10);

 bobsAccount.depositMoney (50);

 OverdraftAccount jimsAccount = new OverdraftAccount (15.05,500,0,05);

 jimsAccount.depositMoney (50);

 // crée un tableau d'objets Account

 // nous pouvons inclure jimsAccount parce que nous 

 // je veux seulement le traiter comme un objet Account

 Compte [] accounts = {bobsAccount, jimsAccount};


 // pour chaque compte du tableau, affiche le solde

 pour (Compte a: comptes)

 {

 System.out.printf ("Le solde est% .2f% n", a.getBalance ());

 }

 La sortie est:

 Le solde est de 60,00

 Le solde est de 65,05 

Tout semble fonctionner comme prévu, ici. Mais que se passe-t-il si OverdraftAccount remplace la méthode getBalance ()? Rien ne l'empêche de faire quelque chose comme ça:

 classe publique OverdraftAccount étend le compte {


 double découvert privé Limite;

 double découvert privé;


 // le reste de la définition de classe n'est pas inclus


 public double getBalance ()

 {

 retour 25,00;

 }

 } 

Si l'exemple de code ci-dessus est à nouveau exécuté, la sortie sera différente car le comportement getBalance () dans la classe OverdraftAccount est appelé pour jimsAccount:

 La sortie est:

 Le solde est de 60,00

 Le solde est de 25,00 

Malheureusement, la sous-classe OverdraftAccount jamais fournir le bon équilibre car nous avons corrompu le comportement de la classe Account par héritage.

Si vous concevez une classe à utiliser par d'autres programmeurs, tenez toujours compte des implications de toute sous-classe potentielle. C'est la raison pour laquelle la classe String ne peut pas être étendue. Il est extrêmement important que les programmeurs sachent que lorsqu'ils créent un objet String, il se comportera toujours comme une chaîne.

Comment empêcher l'héritage

Pour empêcher une classe d'être étendue, la déclaration de classe doit explicitement dire qu'elle ne peut pas être héritée. Ceci est réalisé en utilisant le mot clé "final":

 Compte de classe finale publique {


 } 

Cela signifie que la classe Account ne peut pas être une superclasse et que la classe OverdraftAccount ne peut plus être sa sous-classe.

Parfois, vous souhaiterez peut-être limiter uniquement certains comportements d'une superclasse pour éviter la corruption d'une sous-classe. Par exemple, OverdraftAccount pourrait toujours être une sous-classe de Account, mais il devrait être empêché de remplacer la méthode getBalance ().

Dans ce cas, utilisez le mot-clé "final" dans la déclaration de méthode:

 Compte de classe publique {


 double équilibre privé;


 // le reste de la définition de classe n'est pas inclus


 double getBalance final public ()

 {

 retourner this.balance;

 } 

 } 

Remarquez comment le mot clé final n'est pas utilisé dans la définition de classe. Des sous-classes de compte peuvent être créées, mais elles ne peuvent plus remplacer la méthode getBalance (). Tout code appelant cette méthode peut être sûr qu'elle fonctionnera comme prévu par le programmeur d'origine.

instagram story viewer