初歩的な事かもしれませんが、確認のため、教えて下さい。
Java で、オブジェクトとは「クラスから作られるもの」だと教えられました。
そういうものだと思ってきました。
しかし、Ruby では、クラスもオブジェクトと書いてあります。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html
JavaScript では、関数もオブジェクトと書いてあります。
https://codezine.jp/article/detail/221
そう思って見れば、名前自体、「クラス指向」ではなく、「オブジェクト指向」です。
基となるのは「オブジェクト」で、「プロパティとメソッドを持つ実体」が定義なのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答9件
0
プログラミング用語として**オブジェクト(object)**は主に次の二つの意味で使われます。
- 処理(計算)される対象であり、メモリ上(レジスタ上や概念的な場合もある)に存在する何らかのデータ
- オブジェクト指向におけるクラス(またはそれに相当するものの)のインスタンス
※ なお、コンピューター用語としてはより一般的なデータ全般の意味で使われる場合があります(DBでのオブジェクトやオブジェクトストレージ等)。参考: Object (computer science) - Wikipedia
より端的言うと、上のそれぞれは次のような感じで判断できる何かです。
- 変数に代入できる(変数が束縛できる)何か
レシーバー.メソッド(引数)
のレシーバーとなり得る何か
しかし、言語によっては例外があったり、厳密には異なる事もあるため、一概にこの判断に従うとは言えません。よって、必要十分条件となり得る判断方法ではありませんので、区別するときの参考情報程度に留めてください。
あらゆるインスタンスはデータでもあるため「1.⊇2.」の関係です(例外はたぶん無いと思われます)。言語によっては「1.=2.」ですが、そうでは無い言語も数多く存在します。
オブジェクト指向を言語仕様でサポートしていない言語(以下、非オブジェクト指向言語と言う。C, LISP, Haskell等)では1.の意味で使われる場合が多く、オブジェクト指向を言語仕様でサポートしている言語(以下、オブジェクト指向言語という。Java, Python, Ruby等)では2.の意味で使われる場合が多いです。ただし、言語によっては規格書・仕様書でより厳密に定義されている場合があります。そして、その厳密な定義でのオブジェクトは上の1.とも2.とも異なる場合があります。
結局は言語によってバラバラですので、各言語の仕様を確認しながら、細かく見ていきます。
Java
An object is a class instance or an array.
Javaでの**オブジェクト(object)はクラスのインスタンス(class instance)または配列(array)**です。Javaの配列はクラスのインスタンスではありません。つまり、Javaでは2.に近いですが、配列が含まれるため全く同じではありません。
なお、Javaの変数はオブジェクトを直接束縛するのではなく、オブジェクトへのポインターを束縛します。このポインターとnull
という特別な値(これ自体もオブジェクトでは無い)をあわせて参照値(reference value)と呼ばれます。ただし、null
以外に参照値を直接書く方法は存在しません。
オブジェクトや参照値以外に1.にあたる物としてプリミティブ値(primitive value)が存在します。なお、クラスそのもの(クラスをあらわす識別子による表現されるそれ自体)はオブジェクトでは無いばかりか、1.ですありませんが、.class
等でClassオブジェクトを取り出して、扱うことは可能です。
JavaScript
※ JavaScriptの言語仕様はECMAScriptになります。
4.3.3 object - ECMAScript® 2019 Language Specification
4.3.3 object
member of the type Object
JavaScript(ECMASCript)でのオブジェクト(object)はObject型の一種です(大文字小文字を厳密に区別していることに注意してください。この文章内では大文字から始まるObjectをオブジェクトと表記することはなく、そのまま英語のObjectと表記をします。オブジェクトという表現は全てobjectの事を指します)。Object型は6.1.7 The Object Typeで説明があります。このObject型は0個以上のプロパティの集合体です。プロパティとは言ってしまえばキーとバリューのペアの集合であり、読み取りと書き込みができます。ただし、読み取り専用や、読み取り自体が関数呼び出しになっている特殊なプロパティも存在します。
JavaScriptにおいて、組み込みおよびリテラルやnew
等で作成されたオブジェクトは何からのコンストラクター(costructor、JavaScriptのプロトタイプベースオブジェクト指向においてクラスに相当するもの)のインスタンスです。そういう意味では2.近いように見えます。しかし、Object.create(null)
等とすると、いずれのコンストラクターのインスタンスではないオブジェクト(x instanceof y
がtrue
になるy
が存在しないx
)も作成できます。ですので、やはり2.と全く同じとは言えません。
オブジェクト以外に1.に含まれるモノでプリミティブ値(primitive value)があります。コンストラクターもオブジェクトであり、また、関数(function)でもあります。JavaScriptのクラス構文は一種の糖衣構文であり、クラス(class)というものが内部的にあるわけではありません。
Ruby
JIS X 3017:2013 プログラム言語Ruby p.10
4.14
オブジェクト (object)
状態及び動作をもつ計算実体。
注記 オブジェクトの動作は,そのオブジェクトに対して呼び出すことができるメソッドの集合である。
Rubyのオブジェクトは計算実体です。言語仕様上は1.に近い意味で使われています。クラスのインスタンスであるとか、そういったことは定義に含まれていません。ただし、注記として、なんからのメソッドを持っているだろうと言うことだけがわかります。
よく「Rubyは全てがオブジェクト」と言いますが、状態や動作を持たない計算実体は存在しない(他言語のようなnull
やundefind
みたいなものがない、nil
は虚無という状態を持つし、メソッドも持つ)ため、当たり前の話とも言えます。でも本当に言いたいことは、「全てのオブジェクトは何らかのクラスのインスタンスである」ということです。つまり、「1.=2.」の関係がRubyでは成り立つと言うことです。そのため、Rubyにおいてどちらの意味でオブジェクトという言葉を使っていても、それらが指し示すものは実質同じであると言えます。
なお、クラスはオブジェクトですが、メソッドそのものはオブジェクトではありません。しかし、メソッドをオブジェクト化することはできます。
このように一般的に使われている場合と言語仕様における定義では厳密に異なる場合が多々あり、ここで上げていない言語でも注意が必要です。人や記事や本などによって、厳密な定義での意味で使用している場合もあれば、1.または2.の意味で使用している場合もあります。ただ、ほとんどの言語では非オブジェクト指向言語での1.またはオブジェクト指向言語での2.とその言語仕様で定義されているオブジェクトがほぼ一緒になります。微妙な違い、上で述べたもので言うと、Javaの配列やJavaScriptのObject.create(null)
で作ったオブジェクトだけ気をつければそれほど混乱は無いかと思われます。
その他、手前味噌ですが、下記の記事のオブジェクトの所も参考になるかも知れません。
オブジェクト指向が0.05%も理解できない記事 - Qiita
【追記】
誤解されたままのような気がしますので、質問への直接の回答を記載します。
Java で、オブジェクトとは「クラスから作られるもの」だと教えられました。
仕様書で確認したとおり、Javaのオブジェクトには配列も含まれます。配列はクラスから作られるものではありません。よって、その教えた人はJavaの仕様書で定義されているオブジェクトのことではなく、別の意味のオブジェクトを指して、そのような表現をしたと考えられます。厳密なオブジェクトの定義を知りたいとしている質問者にとっては参考にしてはいけない情報です。
おそらく2.の意味で使われたと考えられますが、実際の所ではその発言をした人本人に聞かないとわかりません。
Ruby では、クラスもオブジェクトと書いてあります。
クラスの機能を実現するにあたって、Rubyでは通常のオブジェクトと同様に扱えるよう言語を設計したと言うことです。別に、クラス自体が通常のオブジェクトと同様に扱えなければならないという必然性はありませんし、扱ってはいけないという必然性もありません。単に、Rubyではクラスもオブジェクトとして扱える仕様を選択しただけです。他言語については、どちらを採用しているからはまさに様々ですので、一概に言えません。
JavaScript では、関数もオブジェクトと書いてあります。
関数の機能を実現するにあたって、JavaScriptでは通常のオブジェクト同様に扱えるよう言語を設計したと言うことです。別に、関数自体が通常のオブジェクトと同様に扱えなければならないという必然性はありませんし、扱ってはいけないという必然性もありません。単に、JavaScriptでは関数もオブジェクトとして扱える仕様を選択しただけです。他言語については、どちらを採用しているからはまさに様々ですので、一概に言えません。
余談ですが、関数が第一級オブジェクトである(間接的ではなく直接的にオブジェクトとして扱えるという意味)ことは関数型プログラミングの書きやすさにおいて非常に重要な意味を持ちます。
名前自体、「クラス指向」ではなく、「オブジェクト指向」です。
「オブジェクト指向(object-oriented)」という名称は、この造語を作り出したアラン・ケイ自身が後悔しているようです。アラン・ケイは「オブジェクト」よりも「メッセージ」が重要であると述べており、その意向に即して「メッセージ指向」というべきだったという人達もいます。いずれにしても「クラス」はオブジェクト指向の本質では無く、実装手段の一つに過ぎません。
基となるのは「オブジェクト」で、「プロパティとメソッドを持つ実体」が定義なのでしょうか?
それはYesでもありNoでもあります。なぜなら、言語によって異なるし、「オブジェクト」という言葉が使われている文脈によって「オブジェクト」がどういう意味なのか異なるからです。
例えば、Javaには「プロパティ」という機能はありません(フィールドとプロパティは異なる機能です)。この時点でJavaへの説明は破綻します。では、Javaにあわせて「フィールドとメソッドを持つ実体」と言った場合も問題が残ります。Javaの仕様では配列もオブジェクトなのですが、配列にはフィールドもメソッドもありません(.length
はフィールドアクセスではなく、特別な構文です)。Javaの仕様上でのオブジェクトの意味で使っていれば、Noになります。しかし、ほとんどの人達は仕様書を細かく見て居らず、上記で最初に書いた2.の意味で使っています。その意味では、Yesとなり、文脈によって異なるという話になります。
他言語に目を向けても同じように例外があったり、逆に、まさしくそう言えたりもします。オブジェクト指向言語では、だいたいがそうと言えそうですが、プログラミングにあまり詳しくない世間一般が考えるオブジェクト指向言語の代表のようなJavaですら、上のような状況です。
結局の所、一概に「オブジェクトとは○○である」ということは言えません。定義が欲しいと言いますが、「仕様上の定義は言語によって異なる」ということしか言えません。仕様の厳密な定義を無視した一般的な意味での使用する場合でも、言語や状況によって1.の意味だったり、2.の意味だったりとバラバラです。文脈等からなんとなく嗅ぎ取る以外はありません。
最後に質問文の最初に触れておきます。
初歩的な事かもしれませんが、
一つの言語についてのみ話をするのであれば、その言語では何が「オブジェクト」と言われているのかは最初に知っておくべき、初歩的なことと言って良いかもしれません。しかし、複数の言語にまたいで「オブジェクト」とは何かを考えることは全くもって初歩的なことではありません。10年以上プログラミングをやって、10個以上は言語を学んで、それでいてやっと曖昧な何か掴めたかなと思うぐらいです。私は未だにこの曖昧な何かを人にうまく説明することができていません。
投稿2019/11/02 15:35
編集2019/11/03 13:18総合スコア21737
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
正確には、クラスから作られるのは インスタンス なのだと思います。
JAVAの場合には クラスはオブジェクトとしては作られていないからオブジェクトはインスタンスだけなので クラスから作られるものがオブジェクトという表現になっているのかと。
rubyではクラスもオブジェクトとして実装してある、ので「クラスから作られるものがオブジェクト」とは言い難いのかと。
rubyにはObjectという名のクラスがあったりして面白いというかややこしいというか。例えば
クラスの継承リスト: Integer < Numeric < Comparable < Object < Kernel < BasicObject
投稿2019/11/02 12:38
総合スコア23567
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/02 13:30
2019/11/02 13:59
0
ベストアンサー
オブジェクトの定義は? ということですが、はっきり言って色々です。ただ、とりあえずオブジェクトは記憶領域上のまとまったデータに対応する、ということは受け入れてもいいでしょう。raccyさんの回答の
1.処理(計算)される対象であり、メモリ上(レジスタ上や概念的な場合もある)に存在する何らかのデータ
2.オブジェクト指向におけるクラス(またはそれに相当するものの)のインスタンス
の1に相当します。
クラスを必ずオブジェクトにしないといけない、ということはないはずです。プログラムでは「クラス」でひな形を記述するけど、その構造はコンパイル時にぜんぶ静的に解決されて消し飛ばされる、という言語設計だってありえます。Javaなどは基本的にはこれです。
この場合は「クラスはオブジェクトとしては存在しない」「メソッドはただの(インスタンス自身を引数に取ったりする)サブルーチンになる」「属性やメソッドへのアクセスはインスタンスのメモリ番地(と属性やメソッドによって予め決められたオフセット)で行う」みたいな方針になります。低レイヤから見ればただの手続き型に近い訳です(これも程度問題ですが)。
まあでもそれはコンパイル言語だからできる芸当だという事実もあって、動的言語というかインタプリタ言語では「クラスもオブジェクト」の方が自然です(今どきのオブジェクト指向プログラミングが当たり前の前提の動的言語から見ればの話)。逆に言うと、これによって動的言語は強力な記述力を獲得しています。
Pythonによる例
python
1>>> class Hoge: # よくあるクラス定義 2... def f(self): 3... print("method f") 4... 5>>> h = Hoge() # インスタンス化 6>>> h.a = "aaa" # クラス定義で書かれていない属性を動的に追加しても全く構わない 7>>> getattr(h, "a") # 文字列(名前)で属性を取れる 8'aaa' 9>>> h.f() # これは普通のメソッド呼び出し 10method f 11>>> Hoge.g = lambda self: print("method g") # クラスの側にメソッドを追加する 12>>> h.g() # インスタンスから叩けるようになる 13method g
クラスオブジェクトがあると、クラスの構造をプログラムから見たりカスタマイズしたりできるので、何かと柔軟になります。「クラスはオブジェクトではない」言語と「クラスもオブジェクト」の言語ではこの辺りのコンセプトにだいぶ違いがあります。
そう思って見れば、名前自体、「クラス指向」ではなく、「オブジェクト指向」です。
クラス指向という言葉も実際にあります。我々が普通読む日本語のwikipediaだとクラスベースになっていますが(英語版だとmore commonly class-orientation
って併記してある)。
クラスベースの対立語はプロトタイプベース(インスタンスベースともいう)ですが、これ実は上述のような「クラスもオブジェクト」の立場とそんなに本質的な違いがありません……。それでもコードの見た目(流儀)をクラスベース風にするかどうかという差異は生じるので、そこで区別できます。
「オブジェクト指向」は更に広い概念で、クラスベース、インスタンスベースのどちらも含みます。
基となるのは「オブジェクト」で、「プロパティとメソッドを持つ実体」が定義なのでしょうか?
基になる、というのがどういうニュアンスなのかによります。つまり見方次第です。
クラスでオブジェクトの(プログラムの、ソフトウェアの)振る舞いが決定されるからクラスが何より大切なんだ! という立場もあるでしょうし、実際にコンピュータの中で生まれたり走ったり書き換えられたり消えたりしているのはオブジェクトだ、という見方をするのであればクラスは存在しないか、存在するとしても他のオブジェクトと等格の存在ということになります。
投稿2019/11/02 19:31
編集2019/11/03 15:27総合スコア30935
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
あまり本筋ではないですが、Javaでもクラスは「Classクラスのオブジェクト」として取り扱えますよね。
「Classクラス」はpublicなフィールドは持ってませんが、メソッドを持っていて、メソッドを通して「Classクラスのオブジェクト」に対して操作ができます。
java
1import java.lang.reflect.Field; 2import java.lang.reflect.Method; 3 4public class IsClassObject { 5 public int fiealdA; 6 public String fieldB; 7 8 public void methodA() { 9 10 } 11 12 public int methodB(int a) { 13 return a * 2; 14 } 15 16 public static void main(String[] args) { 17 Class c = IsClassObject.class; 18 19 // getMethodsやgetFieldsメソッドを呼べばクラスの情報が取得できる 20 for (Method m : c.getMethods()) { 21 System.out.print("Method " + m.getName() + " returns "); 22 System.out.println(m.getReturnType()); 23 } 24 for (Field m : c.getFields()) { 25 System.out.print("Field " + m.getName() + "'s type is "); 26 System.out.println(m.getType()); 27 } 28 29 try { 30 // newInstanceメソッドを呼べばデフォルトコンストラクタを通してインスタンスが作れる 31 IsClassObject o = (IsClassObject) c.newInstance(); 32 System.out.println(o.methodB(10)); 33 } catch (IllegalAccessException ex) { 34 } catch (InstantiationException ex) { 35 } 36 } 37} 38
結果
plain
1Method main returns void 2Method methodA returns void 3Method methodB returns int 4Method wait returns void 5Method wait returns void 6Method wait returns void 7Method equals returns boolean 8Method toString returns class java.lang.String 9Method hashCode returns int 10Method getClass returns class java.lang.Class 11Method notify returns void 12Method notifyAll returns void 13Field fiealdA's type is int 14Field fieldB's type is class java.lang.String 1520
https://ja.wikipedia.org/wiki/オブジェクト指向プログラミング
オブジェクトとは大まかに言うとデータ(変数またはプロパティ)とコード(関数またはメソッド)の複合体を意味しているが、その詳細については様々な解釈が存在する。
オブジェクト指向の定義はまぁ曖昧なものですが、基本的にオブジェクト指向のプログラミングでは「データとコードの複合体」という方針は必ずでてきます。
OOPに基づくプログラムはこのオブジェクトの集合として組み立てられる事になるが、その実装スタイルもまた千差万別である。
プログラミング(言語)にオブジェクト指向というものをどう実装するのかは千差万別だと言ってます。
オブジェクト指向プログラミングというものがオブジェクトつまり「データとコードの複合体」を扱うものだとしましょう。
とすると、プログラマが何をするのか、プログラミングをどうするのか、プログラムがどのように記述されるのか、というのが次に問題になります。
プログラマは、どうにかして「データとコードの複合体」なるものをプログラムとして記述しないといけません。
そのための手段の1つがクラスです。(別にクラスじゃなくても「データとコードの複合体」をうまく記述できるならいいわけです)
次に考えるのは、クラススタイルのオブジェクト指向プログラミングの中でクラスはどういう扱いになるでしょうか? ということですね。
クラスはデータを持っていますか?
Yes
クラスは「名前」という情報を持っています。
「パッケージ」という情報を持っています。
「フィールド」という情報を持っています。
「メソッド」という情報を持っています。
クラスは何か操作できるものですか?
Yes
例えば「新しいインスタンスを作る」という操作が考えられるでしょう。
例えば「あるインスタンスが、そのクラスのインスタンスとして作成されたか調べる」という操作が考えられるでしょう。
データを持っていて、操作できるメソッドがあるなら、クラスもまたクラスとして取り扱う条件はそろっていますね。
様々なクラススタイルのオブジェクト指向プログラミングはクラスの情報は、「Classクラスのインスタンス」として取り扱えることが多いです。
メソッドも「Methodクラスのインスタンス」ですし、フィールドも「Fieldクラスのインタンス」として扱うのが自然になります。
投稿2019/11/02 15:37
総合スコア11231
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
オブジェクト指向にはクラスベースとプロトタイプベースがあり
後者はメジャーじゃないと考えると、おおむねお考えの通りで
あまり問題ないように思います。
※以下余談
用語の定義って時と場合によってビミョーに異なって
きたりしちゃうんで、慎重に調べないと思わぬ
落とし穴があったりしてメンドーですよねえ。
JavaScript はプロトタイプベースに分類されますが、
classなんてのが追加されて一見クラスベースにみえることも
ありますが、実質は前のままという混乱をさそうような
変化もあり、より慎重に見極めないといけなくなってますなあ。
投稿2019/11/02 14:24
総合スコア7460
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
その考え方で合ってると思います。とはいえ、同じ疑問を持ちつつもコードは書けています。
オブジェクト指向については、抽象的な話から理解させようとする書籍が多く、
明確な「定義」は聞きませんよね。
処理する情報を主眼にした明確な定義(考え方)を示さないので、
言語仕様によって若干の差異はあるが、共通しているのは インスタンスの考え方だろうと思います。
処理する情報を主眼に、自分で勝手に解釈しているのが次の通りです。
- オブジェクトは「複数の変数を一纏めにした新しい処理単位で、変数に専用の関数を実装」したもの。
オブジェクトの状態として、クラスとインスタンスがある。
- クラスは、変数や関数が定義された状態を保証するもの。
- インスタンスは、具体的な変数値を渡し、実際の処理単位とするもの。
オブジェクトの亜種には「変数しかないもの」や「関数しかないもの」がある
上記はあくまでも、勝手な定義です。
ただ、この考え方をしたとき、OOPが一気に身につきましたので、「当たらずとも遠からず」なのだろうと思います。
ただ、処理する情報を主眼にしても、言語仕様によって考え方の差があるように思います。
Javaでは Classからオブジェクトが生成されるので、オブジェクトの状態がクラスとは言えませんし、
Jabascriptでは クラスと呼べない、柔軟に変化できるプロトタイプという特徴を持っています。
言語によって生成過程は異なるものの、「インスタンスで処理する」という考え方もできそうです。
投稿2019/11/02 14:50
編集2019/11/02 15:22総合スコア5434
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
皆様、ご回答ありがとうございます。
たくさんのご回答が頂けて、驚いております。
オブジェクトとは「プロパティとメソッドを持つ実体」という考えは、概ね
受け入れられるようで、安心しました。
質問のきっかけは、JavaScript でのプロトタイプベースのオブジェクト指向
の記事です。クラスから生成されないオブジェクトがあるんだと思いました。
PowerShell の記事でも「オブジェクトを扱うシェル」とあり、「クラスは
何なんだろう?」とモヤモヤした気持ちで読んでいました。
オブジェクト自体に「プロパティとメソッドを持つ実体」という定義があるなら、
すんなり理解出来そうです。
皆様のご回答は私の理解を超えるものも多く、ちゃんと調べて理解してからベストアンサーを
決めようかと思っておりましたが、催促されたようですので、現時点で
一番なるほどと思えたhayataka2049様をベストアンサーにさせて頂きます。
他の方もありがとうございました。これから勉強させて頂きます。
投稿2019/11/03 07:10
総合スコア34
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/03 07:13
2019/11/03 07:21
2019/11/03 07:51
0
少し修正しました。
ネコのミケ、イヌのポチがいるとします。
ネコ、イヌといった種別がクラスです。ミケ、ポチといった個体がオブジェクトです。要するに集合と要素の関係です。数学的に書くならばネコ∋ミケ、イヌ∋ポチです。オブジェクト指向は、普通はこの解釈で通ります。
ただし、これを一般化し、種族名∋ネコ、イヌでもあります。言語によっては、クラス自体をオブジェクトとして扱う機能もサポートされています。
オブジェクトとして扱われるものはクラスに限りません。例えばC++では「関数オブジェクト」といって、関数をオブジェクトとして扱う機能がサポートされています。
投稿2019/11/02 13:56
編集2019/11/02 14:32総合スコア4830
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。