Le comportement de finale de la méthode statique
J'ai été jouer avec des modificateurs avec la méthode statique et est venu à travers un comportement bizarre.
Comme nous le savons, les méthodes statiques ne peuvent pas être remplacées, car elles sont associées à une classe plutôt qu'à l'instance.
Donc, si j'ai l'extrait de code ci-dessous, il compile des beaux -
//Snippet 1 - Compiles fine
public class A {
static void ts() {
}
}
class B extends A {
static void ts() {
}
}
Mais si je comprend finale modificateur méthode statique dans Une classe, puis la compilation échoue
ts() dans B ne peut pas remplacer ts() dans Une; méthode de remplacement est statique final.
Pourquoi est-ce qui se passe lorsque la méthode statique ne peut pas être substituée à tous?
- il semble bizarre, +1 pour la question, mais jusqu'à présent, aucun des réponses satisfaisantes.
- Ce n'est pas remplacée. Il est toujours là à A. ts().
Vous devez vous connecter pour publier un commentaire.
Méthodes statiques ne peuvent pas être remplacés, mais ils peuvent être cachés. Le
ts()
méthode de B n'est pas primordiale(qui ne font pas de polymorphisme) lets()
d'Un, mais il va le cacher. Si vous appelezts()
dans B (PASA.ts()
ouB.ts()
... justets()
), l'un des B sera appelée, et pas A. Puisque ce n'est pas l'objet de polymorphisme, l'appelts()
dans Une volonté de ne jamais être redirigé vers celui de B.Le mot-clé
final
va désactiver la méthode d'être caché. Ils ne peuvent donc pas être cachés et de tenter de le faire se traduira par une erreur du compilateur.Espère que cette aide.
A#ts
est héréditaire, et une telle méthode existe déjà dansB
, il suffit d'avoir deux méthodes avec la même signature et un autre modificateur (final
) ne fonctionnerait pas que les surcharges... je souhaite que je pourrais croire à un simple message pour cela, maisCe n'est pas exactement vrai. L'exemple de code vraiment signifie que la méthode ts en B masque la méthode ts en A. Donc ce n'est pas exactement primordial. Plus sur Javaranch il y a une bonne explication.
Méthodes statiques appartiennent à la classe, et non l'instance.
A.ts()
etB.ts()
sont toujours des méthodes distinctes.Le vrai problème est que Java vous permet d'appeler des méthodes statiques sur une instance d'objet. Méthodes statiques avec la même signature de la classe parent sont caché lorsqu'il est appelé à partir d'une instance de la sous-classe. Cependant, vous ne pouvez pas remplacer/masquer finale méthodes.
Vous pensez que le message d'erreur serait d'utiliser le mot caché au lieu de substituée...
Vous pourriez vous retrouver dans la position de penser à faire une méthode static final, tenant compte des éléments suivants:
Avoir les classes suivantes:
Maintenant la "bonne" façon d'appeler ces méthodes pourraient être
qui aurait pour résultat
AB
mais vous pouvez aussi appeler des méthodes sur les instances:qui aurait pour résultat
AB
ainsi.Maintenant, considérez les points suivants:
ce serait imprimer
A
. Qui pourrait vous surprendre, puisque vous sont effectivement avoir un objet de la classeB
. Mais puisque vous êtes en l'appelant à partir d'une référence de typeA
, il va appelerA.ts()
. Vous pouvez imprimerB
avec le code suivant:Dans les deux cas, l'objet est en fait de classe
B
. Mais selon le pointeur qui pointe sur l'objet, vous devez appeler la méthode deA
ou deB
.Maintenant, disons que vous êtes le développeur de la classe
A
et vous souhaitez autoriser les sous-classement. Mais vous voulez vraiment méthodets()
, à chaque fois appelé, même à partir d'une sous-classe, c'est-à fait ce que vous voulez faire et de ne pas être cachés par une sous-version. Ensuite, vous pouvez le fairefinal
et l'empêcher d'être caché dans la sous-classe. Et vous pouvez être sûr que le code suivant va appeler la méthode à partir de votre classeA
:Ok, admittetly qui est en quelque sorte construit, mais il peut faire sens pour certains cas.
Vous ne devriez pas appeler des méthodes statiques sur les instances, mais directement sur les classes - alors vous n'aurez pas ce problème. Aussi IntelliJ IDEA pour exemple va vous montrer un avertissement, si vous appelez une méthode statique sur une instance et ainsi si vous faites une méthode statique finale.
Je pense que l'erreur de compilation est tout à fait trompeur ici. Il ne devrait pas avoir dit "méthode surchargée est statique de la finale.", mais il devrait plutôt avoir dit "méthode de remplacement est définitif.". Le modificateur static est pas pertinente ici.
Le ts() méthode B n'est pas primordial, le ts() la méthode en Un, c'est tout simplement une autre méthode. La classe B ne voit pas le ts() la méthode en A, car il est statique, donc il peut déclarer sa propre méthode appelée ts().
Cependant, si la méthode est définitive, alors le compilateur va ramasser ce qu'il y a un ts() méthode qui ne doit pas être remplacée dans les B.
Une méthode statique ne peut pas être remplacée dans Java, contrairement à la non-méthodes statiques.
Mais ils sont hérités comme statique et non des données membres statiques. C'est pourquoi un non-statique méthode avec le même nom ne peut pas être créé dans la classe parent
La
final
mot-clé veille à ce que le corps de la méthode exécuter à chaque fois un appel à la méthode.Maintenant, si une méthode statique est créé dans la classe enfant avec le même nom et un appel à la méthode, la méthode de la sous-classe est exécuté qui ne devrait pas être le cas si le final est le préfixe devant le nom de la méthode statique de la classe parent. D'où le mot-clé final restreint la création de la méthode avec le même nom dans la classe enfant.