静的メソッドがメソッドと見なされるのはなぜですか?


135

コースの一部のコードの説明を書いていますが、誤って単語methodfunction交換して使用しています。私は戻って言葉遣いを修正することにしましたが、私の理解の穴にぶつかりました。

私が理解していることから、サブルーチンはfunctionクラスのインスタンスに作用しない場合(その効果は明示的な入力/出力に制限されます)、methodクラスのインスタンスに作用する場合(それはインスタンスへの副作用を排除します)。

このトピックに関しては良い議論があります。受け入れられた回答の定義によれmethodば、インスタンスは暗黙的に渡されることはなく、インスタンスのメンバーにアクセスできないため、static は実際には関数である必要があります。

ただし、これは気になっていますが、methods実際にはstatic は関数ではありませんか?

それらの定義により、クラスの特定のインスタンスには作用しません。彼らは関係のためにクラスに「結びついている」だけです。静的サブルーチンを「メソッド」と呼ぶ見栄えの良いサイトをいくつか見たことがあります(OracleFredosaurusProgrammingSimplified)ので、これらはすべて用語を見落としているか、何か不足しています(私の推測は後者です)。 。

正しい文言を使用していることを確認したいのですが。
誰かがこれを片付けることができますか?


2
私はいつもそれがphpの関数とJavaのメソッドだと思っていました。基本的に同じものを別の名前で
JK

19
理論的なコンピューターサイエンスと言語がそれを適用する方法には違いがあります。JLSは区別せず、メソッドと呼びます。
Jeroen Vannevel


2
Pythonで「関数」と「メソッド」の定義を見ると興味深いかもしれません、違いあります。基本的に、関数はシンボルテーブルと呼び出し規約を含むコードのチャンクですが、メソッドは関数をクラスに入れると得られます。ただし、Pythonを知っている人でも、その違いは非常に微妙です。
デビッドZ

2
理論を学んでいたとき、関数は値を返し、手順は返さないことを学びました。次に、Java呼び出し関数とプロシージャメソッドについて学びました。現在、私は関数型プログラムを試しており、関数はべき等です。これらの用語は、状況によって意味が変わります。
Emory、2015年

回答:


123

8.4.3.2からのこの引用は、次のことに役立ちます。

宣言さstaticれたメソッドは、クラスメソッドと呼ばれます。

宣言されていないメソッドはstaticインスタンスメソッド [...] と呼ばれます

  • クラスメソッド:クラスに関連付けられます。
  • インスタンスメソッド:インスタンスに関連付けられています。

Javaは単に「オブジェクト指向を考える」ことを求めています。また、静的メソッドは、状態を含む可能性のある周囲のスコープにアクセスできます。ある意味で、クラスはオブジェクト自体のようなものです。


そうは言っても、「関数」はJavaでの実行の単位として技術的には正しいですが、すべてのJava関数はクラスまたはインターフェースの一部であるため、ほとんどすべてのJavaで推奨される命名法は「メソッド」です(ラムダを除く。私が知らない他のいくつかの事柄)。
Shotgun Ninja

1
ラムダは実際には匿名の内部クラスであり、@FunctionalInterface注釈があり、内部には1つのメソッドがあります。ラムダは単なる構文上の砂糖であり、その点で新しいものはありません。
Adam Arold、2015年

1
@AdamArold Lambdasは、匿名の内部クラスよりもかなり洗練されています。たとえば、非キャプチャラムダは、特定の式の複数の評価にわたってインスタンスを共有できます。(ただし、最終的には静的メソッドとインスタンスメソッドにコンパイルされます。)
Radiodef '23年

@Radiodef多分それを表現するより良い方法は、「ラムダ式を含むファイル以外のファイルに変更を加えることなく、すべてのラムダ式を同等の非ラムダ式で置き換えることができる」かそのようなものでしょう。
user253751

4
私は恥ずかしい。私はScalaの出身ですが、クラス自体がオブジェクトのようなものであるという事実を見逃していました。ありがとうございました。
発癌性

80

簡単な答えは、Javaがすべてを「メソッド」と呼ぶことを決めたとき、彼らは理論的なコンピュータサイエンスにおける関数とメソッドの区別を気にしなかったということです。


3
そのとおり。までとJava 7を含め、あなたもで単語「機能」が見つかりません言語仕様
アーウィンBolwidt

4
この回答の単純さを気に入っているだけでなく、Radiodefの回答は、クラス自体がオブジェクトとして機能するという重要な点について言及しているため、順調に進んでいると思います。ありがとう、結構です。
カルシジェネート、2015年

2
興味深いことに、これは、関数とサブルーチンを区別しないという以前の言語の決定と並行しています。
Random832

4
この回答が非常に多くの賛成票を獲得したことに不愉快に驚いています。まず、この回答は、クラスメソッドが存在しないことを装っています。次に、これはJavaで導入された概念ではありません。たとえば、クラスメソッドはSmalltalkにすでに存在し、Javaが登場するまで数十年間存在していました。
マルコム

1
@マルコム私はあなたに同意する必要があります。他の回答を検討した後、これは間違っているようです。Javaクリエーターの側には無関心ではありませんが、彼らが本当に気にかけずに、結局それを正しく命名してしまう場合を除きます。
Carcigenicate

26

静的メソッドは正確には関数ではありません。違いはわずかですが重要です。

与えられた入力パラメーターのみを使用する静的メソッドは、基本的に関数です。

しかし、静的メソッドは、静的変数や他の静的関数(静的変数を使用する)にアクセスする可能性があるため、静的メソッドは、本質的にstatelessである関数とは根本的に異なる状態を持つ可能性があります。(補遺:プログラマーは「関数」を定義として使用することでそれほど厳密ではないことがよくありますが、コンピューターサイエンスの厳密な関数は入力パラメーターのみにアクセスできます)。したがって、静的フィールドにアクセスするこのケースを定義することは、静的メソッドが常に関数であると言っても無効です。

「静的メソッド」の使用を正当化するもう1つの違いは、Cで、どこからでもアクセスできるグローバル関数とグローバル変数を定義できることです。静的メソッドを含むクラスにアクセスできない場合、メソッドにもアクセスできません。したがって、「静的メソッド」は、グローバル関数とは対照的に、その範囲が設計によって制限されています。


2
私はこの答えが好きですが、いくつかのことをよりよく理解したいと思います。これは、関数とメソッドではなく、「純粋な」関数と「副作用のある」関数ではありませんか?それとも、副作用のためにそのような方法であるということですか?ここでブレーンストーミングを行っています。
Nadir Sampaoli、

2
この答えは正しいです。ただし、多くの(ほとんどの)言語の関数はグローバル変数にアクセスできるため、厳密にステートレスではない(同じ入力、同じ出力)ことが多いと主張できます。また、Java静的メソッドの場合、クラス変数にアクセスすることは、「グローバル」(つまり、関数/メソッドに対してローカルではない)変数にアクセスすることと同等と見なすことができます。クラスインスタンスは名前空間の一種です。
leonbloy

1
@leonbloy HaskellのようなPure Functionalプログラミング言語は完全にステートレスです。グローバル変数と呼ぶことができるものは何もありません。
Thorsten S.

17

Javaでは、ユーザー定義クラスは実際にはjava.lang.Classのサブクラスのインスタンスです。

この意味で、静的メソッド概念クラスのインスタンスに付加されます。それらはjava.lang.Classのサブクラスのインスタンスに付加されます。

これを念頭に置いて、「クラスメソッド」(Javaの静的メソッドの別名)という用語が意味を持ち始めます。「クラスメソッド」という用語は、Objective C、Smalltalk、JLSなど、さまざまな場所で使用されています。


このサブクラスの2つのインスタンスを持つことは可能ですか?
Random832

もちろん、クラスを異なるクラスローダーにロードすることもできます(「CustomClassをCustomClassにキャストできません」というメッセージでClassCastExceptionsを取得する理由)。
dunni 2015年

2
@ Random832-ちょっと。各インスタンスが独自の個別のクラスローダーを持っている限り、同じJVM内の同じクラスサブクラスの2つ(またはそれ以上)のインスタンスを持つことができます。クラスローダーごとに同じClassサブクラスを複数回インスタンス化することはできません。これは少し混乱し、古典的なOOの概念との類似点がこの時点で少し薄くなり始めます。
マイククラーク

@MikeClark私がそれをするなら、彼らは本当に同じですか?同様に、クラス自体がその別のインスタンスであっても、Classサブクラスは同じクラスになりますか?クラスローダーは私をかなり混乱させます。参照を渡すことにより、同じクラスの別のクラスローダーのインスタンスから、あるクラスローダーのクラスのインスタンスの静的メソッドを(リフレクションなしで)呼び出すことができますか?彼らが異なる方法を持っている場合はどうなりますか?
Random832

1
@ Random832「ソート?」純粋にOO理論の観点から見ると、クラスの2つのインスタンスは本当にまったく同じですか?同じクラスの少なくとも2つのその他の点で同一のインスタンスは、異なるアドレスを持ちます。それ以外の場合、どうすれば2つのことを実現できますか?何かとまったく同じ唯一のものは、それ自体です。
マイククラーク

11

コンピュータサイエンスでは、関数は明らかに静的メソッドにマッピングされます。ただし、クラスの「メソッド」は「メンバー」(フィールドメンバー、メソッドメンバー)のように少し一般的です。のような文言があります

データメンバーとメソッドメンバーには、2つの異なる名前空間があります。.xと.x()は共存できます。

その理由は、哲学者のルートヴィヒウィトゲンシュタインが言ったように、言語はさまざまなコンテキストを持つツールであることです。「メソッド」は、「メンバー」を分類するための上記の引用における優れたモニカです。


9

あなたの考えは正しく、理にかなっています。これは、Javaコミュニティで確立された用語ではありません。用語が存在する理由を理解するのに役立ついくつかの内部について説明します。

Javaは、クラスベースのオブジェクト指向言語です。メソッドは常にクラスまたはインスタンスのメンバーです(これは他のプログラミング言語にも有効な一般的なステートメントです)。クラスとインスタンスは両方ともオブジェクトであると考えます。

インスタンスメソッド(動的)

このメソッドをクラスから直接呼び出すことはできません。インスタンスを作成する必要があります。各インスタンスはそのメソッドを参照します。まったく同じメソッドシグネチャでメソッド定義を上書きできます(サブクラス化時)。つまり、参照は別のメソッド(同じシグネチャを持つが、メソッド本体は異なる場合があります)を指します。メソッドは動的です。

クラスメソッド(静的)

このメソッドは、クラスから直接呼び出すことしかできません。つまり、そのクラスのインスタンスを作成する必要はありません。プログラム全体でそのメソッドのグローバル定義は1つだけです。メソッドが静的であると宣言されている場合、プログラム全体に対して有効な定義は1つしかないため、まったく同じメソッドシグネチャを上書きすることはできません。メソッドはクラスオブジェクト自体のメンバーであることに注意してください。インスタンスには、そのメソッドへのすべての同じ一意の(および修正)参照があります。


7

以下は、Scalaをニーモニックとして使用した、別の用語
ですobject。Scalaには、暗黙的に定義されたクラスのシングルトンインスタンスであるsがあります。

クラスの単一のインスタンスを操作するため、定義に応じて、object メソッドに属するこれらのサブルーチンを呼び出すことができます。
さらに、オブジェクトはクラスAも定義し、オブジェクトA内のすべてのメソッドをクラスAの静的メソッドとして作成します(Javaとのインターフェース用) [2]

したがって、JavaクラスAの静的メソッドはScalaシングルトンインスタンスと同じメンバーにアクセスし、定義ごとにクラスAの(静的)メソッドを呼び出す必要があると言えます。


素晴らしい比較。私はScalaを知っているので、あなたのobject参照は非常に理にかなっています。ありがとうございました。
Carcigenicate

2

もちろん、主な違いは、メソッドはメソッドパラメータだけでなく、静的フィールドを使用できることです。しかし、もう1つあります-ポリモーフィズム!評価結果Class A.doTheSameStaticMethod()およびClassB.doTheSameStaticMehod()はクラスに依存します。この場合、機能は無力です。


1

各クラスには、クラスのサブクラスのインスタンスである、それを表すオブジェクトがありますClass。静的メソッドは、実際にはこれらのオブジェクトのインスタンスメソッドであり、Classのサブクラスのインスタンスです。静的フィールドの形で状態にアクセスできるため、単なる(状態のない)関数であることに限定されません。それらはメソッドです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.