Quel est l'équivalent de la finale de Java en C #?

560

Quel est l'équivalent de Java finalen C #?

Nosrama
la source
131
Un commentaire en haut de la classe disant "Si vous remplacez cette classe, vous êtes viré!" (bien sûr, c'est une blague :)
Hemant

Réponses:

861

Le finalmot-clé a plusieurs usages en Java. Il correspond à la fois aux mots clés sealedet readonlyen C #, selon le contexte dans lequel il est utilisé.

Des classes

Pour empêcher le sous-classement (héritage de la classe définie):

Java

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

Les méthodes

Empêcher le remplacement d'une virtualméthode.

Java

public class MyClass
{
    public final void myFinalMethod() {...}
}

C #

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Comme le souligne Joachim Sauer, une différence notable entre les deux langages ici est que Java par défaut marque toutes les méthodes non statiques comme virtual, tandis que C # les marque comme sealed. Par conséquent, vous n'avez besoin d'utiliser le sealedmot clé en C # que si vous souhaitez arrêter de surcharger une méthode qui a été explicitement marquée virtualdans la classe de base.

Variables

Pour autoriser une variable à être affectée une seule fois:

Java

public final double pi = 3.14; // essentially a constant

C #

public readonly double pi = 3.14; // essentially a constant

En remarque, l'effet du readonlymot - clé diffère de celui du constmot - clé dans la mesure où l' readonlyexpression est évaluée au moment de l' exécution plutôt qu'au moment de la compilation , permettant ainsi des expressions arbitraires.

Noldorin
la source
15
J'ajouterais que toutes les méthodes non statiques de Java sont virtuelles par défaut. Donc, en C #, vous pouvez simplement laisser de côté le virtuel dans la définition initiale, vous devrez utiliser "final" pour éviter que les sous-classes ne le remplacent en Java
Joachim Sauer
167
bonne réponse - il y a une utilisation supplémentaire de "final" en java - sur une variable locale ou un paramètre de méthode pour éviter de le réaffecter. Il n'y a pas d'équivalent direct c # de cela.
serg10
17
readonlyles variables membres peuvent être modifiées dans les constructeurs: pastebin.com/AzqzYGiA
récursif
8
Notez également: si vous déclarez une variable membre comme finale en Java, le compilateur se plaindra, sinon tous les constructeurs attribuent une valeur dans chaque chemin de code, tandis que C # émet uniquement un avertissement dans ce scénario avec des variables membres en lecture seule
Mene
1
@NickolayKondratyev: Oui, mon exemple était implicite en ce que vous devez être un sous-classement d'une autre classe. Vous n'avez pas vraiment besoin de l'interface; c'est superflu, mais sinon cela semble à peu près juste.
Noldorin
180

Ça dépend du contexte.

LukeH
la source
1
En fait, il n'est pas nécessaire qu'une variable finale soit affectée lorsqu'elle est déclarée. 'final' signifie que la variable doit être affectée par un chemin de code avant d'être référencée et qu'aucun chemin de code ne permet d'affecter la variable plus d'une fois. Cela s'applique aux variables d'instance, ce qui signifie en fait que les constructeurs doivent affecter explicitement la variable.
Jay
31
+ pour For a final local variable or method parameter, there's no direct C# equivalentune énorme distinction.
Daniel B. Chapman
1
Si vous instanciez , const pour une variable locale peut être utilisé. Ce n'est pas équivalent car bien sûr, final vous permet de déclarer et d'initialiser séparément (et donc d'avoir des valeurs différentes), mais juste au cas où vous ne le sauriez pas ...
Griknok
3
constne peut être utilisé que sur des types de valeur. Pour autant que je sache, il n'y a aucun moyen de faire une constante efficace pour un type de référence local.
jocull
2
@jocull Avec les chaînes étant la seule exception.
Raimund Krämer
46

Ce que tout le monde manque ici, c'est la garantie de Java d'une affectation définitive pour les variables de membre final.

Pour une classe C avec la variable de membre final V, chaque chemin d'exécution possible à travers chaque constructeur de C doit assigner V une seule fois - faute d'attribuer V ou d'affecter V deux fois ou plus, une erreur se produira.

Le mot clé en lecture seule de C # n'a aucune garantie de ce type - le compilateur est plus qu'heureux de laisser les membres en lecture seule non affectés ou de vous permettre de les affecter plusieurs fois au sein d'un constructeur.

Ainsi, final et readonly (au moins en ce qui concerne les variables membres) ne sont certainement pas équivalents - final est beaucoup plus strict.

Un gars
la source
7

Comme mentionné, sealedest un équivalent de finalpour les méthodes et les classes.

Quant au reste, c'est compliqué.

  • Pour les static finalchamps, static readonlyc'est la chose la plus proche possible. Il vous permet d'initialiser le champ statique dans un constructeur statique, qui est assez similaire à l'initialiseur statique en Java. Cela s'applique à la fois aux constantes (primitives et objets immuables) et aux références constantes aux objets mutables.

    Le constmodificateur est assez similaire pour les constantes, mais vous ne pouvez pas les définir dans un constructeur statique.

  • Sur un champ qui ne doit pas être réaffecté une fois qu'il quitte le constructeur, readonlypeut être utilisé. Ce n'est pas égal cependant - finalnécessite exactement une affectation, même dans le constructeur ou l'initialiseur.
  • Il n'y a pas d'équivalent C # pour une finalvariable locale à ma connaissance. Si vous vous demandez pourquoi quelqu'un en aurait besoin: vous pouvez déclarer une variable avant un if-else, un switch-case ou autre. En le déclarant définitif, vous faites en sorte qu'il soit attribué au plus une fois.

    Les variables locales Java en général doivent être affectées au moins une fois avant d'être lues. À moins que la branche ne saute avant la lecture de la valeur, une variable finale est affectée exactement une fois. Tout cela est vérifié au moment de la compilation. Cela nécessite un code bien comporté avec moins de marge d'erreur.

En résumé, C # n'a pas d'équivalent direct de final. Bien que Java manque de fonctionnalités intéressantes de C #, il est rafraîchissant pour moi, en tant que programmeur Java, de voir où C # ne parvient pas à fournir un équivalent.

Vlasec
la source
6

Classe Java finale et méthode finale -> scellées. Variable membre Java final -> en lecture seule pour la constante d'exécution, const pour la constante de temps de compilation.

Aucun équivalent pour la variable locale finale et l'argument de méthode final

Vijayakumarpl
la source
0

scellé

x2.
la source
8
Cela ne représente qu'une partie de la réponse car cela dépend du contexte et l'ajout d'une explication et / ou d'exemples le rendra beaucoup plus digeste pour ceux qui ont besoin d'aide
Rune FS