Pourquoi une méthode statique est-elle considérée comme une méthode?

135

J'écris une explication pour un code pour un cours, et j'utilise accidentellement les mots methodet de functionmanière interchangeable. J'ai décidé de revenir en arrière et de corriger le libellé, mais je suis tombé sur un trou dans ma compréhension.

D'après ce que je comprends, un sous-programme est un functions'il n'agit pas sur une instance d'une classe (son effet est limité à son entrée / sortie explicite), et est un methods'il opère sur une instance d'une classe (il peut porter effets secondaires sur l'instance qui la rendent impure).

Il y a une bonne discussion ici sur le sujet. Notez que d'après les définitions de réponse acceptées, un statique methoddevrait en fait être une fonction car une instance n'est jamais transmise implicitement et n'a accès aux membres d'aucune instance.

Avec ceci est l'esprit cependant, ne devrait pas statique methods être réellement des fonctions?

De par leur définition, ils n'agissent pas sur des instances particulières d'une classe; ils ne sont "liés" à la classe qu'à cause de leur relation. J'ai vu quelques bons sites qui font référence aux sous-programmes statiques comme des «méthodes» ( Oracle , Fredosaurus , ProgrammingSimplified ), donc soit ils ignorent tous la terminologie, soit il me manque quelque chose (je suppose que c'est la dernière) .

Je voudrais m'assurer que j'utilise le bon libellé.
Quelqu'un peut-il clarifier cela?

Carcigénicate
la source
2
J'ai toujours pensé que c'était une fonction en php et une méthode en Java. Fondamentalement la même chose avec des noms différents
JK
19
Il y a une différence entre l'informatique théorique et la façon dont une langue l'applique. Le JLS ne fait aucune distinction et l'appelle une méthode.
Jeroen Vannevel
2
Il pourrait être intéressant de regarder les définitions de «fonction» et de «méthode» en Python, où il y a une différence: fondamentalement, une fonction est un morceau de code avec une table de symboles et une convention d'appel, alors qu'une méthode est ce que vous obtenez lorsque vous mettez une fonction dans une classe. La différence est cependant assez subtile, même pour les personnes qui connaissent Python.
David Z
2
Lorsque j'apprenais la théorie, j'ai appris que la fonction renvoie une valeur et pas la procédure. Ensuite, j'ai appris les fonctions d'appels java et les méthodes de procédures. Maintenant, j'essaye le programmjng fonctionnel et une fonction est idempotente. Les termes changent de sens dans le contexte.
emory

Réponses:

123

Cette citation de 8.4.3.2 peut aider:

Une méthode déclarée staticest appelée méthode de classe .

Une méthode qui n'est pas déclarée staticest appelée méthode d'instance [...].

  • Méthodes de classe: associées à une classe.
  • Méthodes d'instance: associées à une instance.

Java veut simplement que vous "pensiez orienté objet". En outre, les méthodes statiques ont accès à une portée environnante qui peut inclure l'état. D'une certaine manière, la classe est comme un objet lui-même.

Radiodef
la source
Cela étant dit, alors que «fonction» est techniquement correcte en tant qu'unité d'exécution en Java, la nomenclature préférée dans presque tout Java est «méthode», car toutes les fonctions Java font partie d'une classe ou d'une interface (à l'exclusion des lambdas, et peut-être d'autres choses dont je ne suis pas au courant).
Shotgun Ninja
1
Les lambdas sont en fait des classes internes anonymes avec l' @FunctionalInterfaceannotation et avec 1 méthode sous le capot. Un lambda n'est qu'un sucre syntaxique et à cet égard il n'y a rien de nouveau.
Adam Arold
1
@AdamArold Lambdas est un peu plus sophistiqué qu'une classe interne anonyme. Par exemple, les lambdas non capturants peuvent partager une instance sur plusieurs évaluations d'une expression particulière. (Mais vous avez raison, ils sont finalement compilés en méthodes statiques et d'instance.)
Radiodef
@Radiodef Peut-être qu'une meilleure façon de le formuler serait "Toutes les expressions lambda peuvent être remplacées par des expressions non lambda équivalentes, sans apporter de modifications aux fichiers autres que celui contenant l'expression lambda" ou quelque chose du genre.
user253751
4
Je suis embarrassé. Je viens de Scala et j'ai quand même réussi à manquer le fait que la classe elle-même ressemble à un objet. Je vous remercie.
Carcigenicate
80

La réponse simple est que lorsque Java a décidé d'appeler tout une «méthode», il ne se souciait pas de la distinction entre une fonction et une méthode en informatique théorique.

Bitcoin M
la source
3
C'est vrai. Jusqu'à et y compris Java 7, vous ne trouverez même pas le mot «fonction» dans la spécification
Erwin Bolwidt
4
Autant que j'aime la simplicité de cette réponse, je pense que la réponse de Radiodef est plus sur la bonne voie car elle mentionne le point clé que la classe elle-même agit comme un objet. Merci quand même.
Carcigenicate
2
Il est intéressant de noter que cela est parallèle aux décisions des langages antérieurs de ne pas différencier les fonctions et les sous-programmes.
Random832
4
Je suis désagréablement surpris que cette réponse ait reçu autant de votes positifs. Premièrement, cette réponse prétend que les méthodes de classe n'existent pas. Deuxièmement, ce n'est guère un concept introduit en Java. Les méthodes de classe existaient déjà dans Smalltalk, par exemple, qui était là pendant des décennies avant que Java ne devienne une chose.
Malcolm
1
@Malcolm Je suis d'accord avec vous. Après avoir examiné les autres réponses, cela semble faux. Ce n'est pas de l'apathie de la part du créateur Java, à moins qu'ils ne s'en foutent vraiment mais finissent par le nommer correctement malgré tout.
Carcigenicate
26

Les méthodes statiques ne sont pas exactement des fonctions, la différence est subtile, mais importante.

Une méthode statique utilisant uniquement des paramètres d'entrée donnés est essentiellement une fonction.

Mais les méthodes statiques peuvent accéder à des variables statiques et à d'autres fonctions statiques (utilisant également des variables statiques) de sorte que les méthodes statiques peuvent avoir un état qui est fondamentalement différent d'une fonction qui est par définition sans état . (ADDENDA: Bien que les programmeurs ne soient souvent pas aussi stricts avec l'utilisation de «fonction» comme définition, une fonction stricte en informatique ne peut accéder qu'aux paramètres d'entrée). Donc, en définissant ce cas d'accès aux champs statiques, il n'est pas valide de dire que les méthodes statiques sont toujours des fonctions.

Une autre différence qui justifie l'utilisation de la "méthode statique" est que vous pouvez définir en C des fonctions globales dérivées et des variables globales accessibles partout. Si vous ne pouvez pas accéder à la classe qui contient des méthodes statiques, les méthodes sont également inaccessibles. Ainsi, les «méthodes statiques» sont limitées dans leur portée par conception contrairement aux fonctions globales.

Thorsten S.
la source
2
J'aime bien cette réponse, mais j'aimerais mieux comprendre certaines choses. N'est-ce pas plus une fonction «pure» vs «à effet secondaire», plutôt qu'une fonction vs méthode? Ou est-ce qu'une méthode est telle en raison d'effets secondaires? Je fais juste un brainstorming ici.
Nadir Sampaoli
2
Cette réponse est juste. Cependant, on pourrait soutenir que les fonctions dans de nombreux langages (la plupart?) Peuvent accéder aux variables globales, donc elles ne sont souvent pas strictement sans état (même entrée, même sortie). Et dans le cas des méthodes statiques Java, accéder aux variables de classe pourrait être considéré comme équivalent à accéder aux variables "globales" (c'est-à-dire non locales à une fonction / méthode) - l'instance de classe étant une sorte d'espace de noms.
leonbloy
1
@leonbloy Pure Les langages de programmation fonctionnels comme Haskell sont complètement sans état; il n'y a rien qui puisse être appelé une variable globale.
Thorsten S.
17

En Java, une classe définie par l'utilisateur est en fait une instance d'une sous-classe de java.lang.Class.

En ce sens, les méthodes statiques sont attachées à une instance d'une classe conceptuelle: elles sont attachées à une instance d'une sous-classe de java.lang.Class.

Dans cet esprit, le terme «méthode de classe» (un autre nom pour les méthodes statiques de Java) commence à avoir un sens. Et le terme «méthode de classe» peut être trouvé à de nombreux endroits: Objective C, Smalltalk et JLS - pour n'en nommer que quelques-uns.

Mike Clark
la source
Est-il possible d'avoir deux instances de cette sous-classe?
Random832
Bien sûr, vous pouvez charger une classe dans différents chargeurs de classe (la raison de l'obtention de ClassCastExceptions avec le message "ne peut pas convertir CustomClass en CustomClass").
dunni
2
@ Random832 - en quelque sorte. Vous pouvez avoir deux (ou plus) instances de la même sous-classe de classe dans la même machine virtuelle Java, à condition que chaque instance dispose de son propre chargeur de classe distinct. Vous ne pouvez pas instancier la même sous-classe de classe plus d'une fois par chargeur de classe. Cela devient un peu déroutant et les analogies avec les concepts OO classiques commencent à être un peu étirées à ce stade.
Mike Clark
@MikeClark si je fais ça, sont-ils vraiment les mêmes? Par exemple, la sous-classe Class sera-t-elle la même classe même si la classe elle-même en est une instance différente? Les chargeurs de classe sont assez déroutants pour moi. Puis-je appeler (sans réflexion) une méthode statique de l'instance d'un chargeur de classe d'une classe à partir d'une instance d'un autre chargeur de classe de la même classe, en lui faisant passer une référence? Et s'ils ont des méthodes différentes?
Random832
1
@ Random832 "En quelque sorte?" D'un point de vue purement théorique OO, est-ce que deux instances d'une classe sont vraiment exactement les mêmes? Au moins deux instances identiques de la même classe auront des adresses différentes. Sinon, comment pouvons-nous avoir deux d'une chose? La seule chose qui est exactement la même chose que quelque chose, c'est la chose elle-même.
Mike Clark
11

En informatique, la fonction correspond clairement à une méthode statique. Mais «méthode» d'une classe est un peu générique, comme «membre» (membre de champ, membre de méthode). Il y a des libellés comme

Les membres de données et les membres de méthode ont deux espaces de nom distincts: .x et .x () peuvent coexister.

Donc, la raison en est que, comme l'a dit le philosophe Ludwig Wittgenstein, le langage est un outil avec des contextes différents. "Méthode" est un joli surnom dans la citation ci-dessus pour catégoriser un "membre".

Joop Eggen
la source
9

Votre pensée est juste et elle a du sens. Ce n'est tout simplement pas une terminologie établie dans la communauté Java. Laissez-moi vous expliquer quelques éléments internes qui peuvent aider à comprendre pourquoi la terminologie subsiste.

Java est un langage orienté objet basé sur des classes. Une méthode est toujours membre d'une classe ou d'une instance (il s'agit d'une instruction générale valable également pour d'autres langages de programmation). Nous pensons que la classe et l'instance sont les deux objets.

Méthode d'instance (dynamique)

Vous ne pouvez pas appeler cette méthode directement depuis une classe, vous devez créer une instance. Chaque instance fait référence à cette méthode. Vous pouvez écraser une définition de méthode avec exactement la même signature de méthode (lors du sous-classement), c'est-à-dire que la référence pointe vers une méthode différente (qui a la même signature, mais peut avoir un corps de méthode différent). La méthode est dynamique.

Méthode de classe (statique)

Vous ne pouvez invoquer cette méthode que depuis la classe directement, c'est-à-dire que vous n'avez pas besoin de créer une instance de cette classe. Il n'y a qu'une seule définition globale de cette méthode dans l'ensemble du programme. Vous ne pouvez pas écraser exactement la même signature de méthode lorsque la méthode est déclarée statique, car il n'y a qu'une seule définition valide pour l'ensemble du programme. Notez que la méthode est membre de l'objet de classe lui-même, les instances ont toutes la même référence unique (et fixe) à cette méthode.

Ely
la source
7

Voici une autre interprétation de la terminologie, utilisant Scala comme mnémonique:
Dans Scala, vous avez des objects, qui sont des instances singleton d'une classe implicitement définie1 .

Selon votre définition, nous pouvons appeler ces sous-programmes appartenant aux object méthodes , car ils opèrent sur une seule instance de la classe.
De plus, l'objet définira également la classe A et créera toutes les méthodes de l'objet A en tant que méthodes statiques sur la classe A (pour l'interfaçage avec Java) [2] .

Par conséquent, nous pouvons dire que les méthodes statiques de la classe Java A accèdent aux mêmes membres que l'instance singleton Scala, qui, selon votre définition, méritent alors d'être appelées méthodes (statiques) de classe A.

mucaho
la source
Excellente comparaison. Je connais Scala, donc votre objectréférence a beaucoup de sens. Je vous remercie.
Carcigenicate
2

Bien sûr, la principale différence est que la méthode peut utiliser des champs statiques, pas seulement des paramètres de méthode. Mais il y en a un autre: le polymorphisme! Les résultats de l'évaluation Les classes A.doTheSameStaticMethod () et ClassB.doTheSameStaticMehod () dépendront de la classe. Dans ce cas, la fonction est impuissante.

Павел Бивойно
la source
1

Chaque classe a un objet pour la représenter qui est une instance d'une sous-classe de la Classclasse. Les méthodes statiques sont en réalité des méthodes d'instance sur ces objets qui sont des instances d'une sous-classe de Class. Ils ont accès à l'état sous la forme de champs statiques, ils ne sont donc pas limités à de simples fonctions (sans état). Ce sont des méthodes.

Bohème
la source