• 締切済み

Javaオブジェクト指向について

javaを覚えています。そこでどうしてもオブジェクト指向の考え方が分かりません。 本を読んでもいまいちわかりません。 本ではオブジェクトは「物」と記載していますが、いまいちわかりません。 例を交えて教えて下さい。 例)りんご、人等交えて教えて頂けるとたすかります。

みんなの回答

回答No.6

うん、#5氏は重要な示唆をしてるね。 >  以上のように、メインルーティンで変数定義を済ませた瞬間には、少なくともコード上では結果が出ているような事態、これが自分の思う理想的なオブジェクト志向プログラミングです。 これは実はオブジェクト指向に限った話じゃない。「理想論」としては全てのソフトウェアの「作り方」、っつーか、「どうパーツを分解して作るのか」と言う話だ。 全てのソフトウェアは3つの要素から成り立ってる。そしてその3つの要素を組み合わせる。 オブジェクト指向だろうが、手続き型プログラミングだろうが、目指す先は「コンピュータサイエンス的には」同じだ。 #5氏は >  「実行者」Inputterは、とにかく生成時に入力を受け取り、それを処理に適したInputData型に成型する。それを外部に公開するのが、.Data関数。 > 「処理実行者」Runnerは生成時にコンストラクターを通じて入力情報Input_Dataを受け取り、計算処理を行い、処理結果を出力に適したRunData型に成型する。それを外部に公開するのは、やはり .Data関数。 > 「出力実行者」Outputterは、同様に生成時にコンストラクターを通じてRun_Dataを受け取り、出力を行う。この実行者も、出力用のマン・マシンインターフェイスや出力ファイルに関わる、低レベルオブジェクトと裏でつながってるものとします。 と言う用語をアテてるが、実はこれらはコンピュータサイエンス的には上から順番にRead(読み込み部)、Eval(Evaluator: 評価器)、Print(表示部)、と呼ぶ。 基本的に「この3つが別々のパーツとして構成されるように」プログラムを書く、ってのがコンピュータサイエンス的な「プログラミング書法」だ。 最近のJavaだと開発環境が進歩して、jshellなるJavaインタプリタを同梱してくれるようになった。 ・新機能を手軽に試すためのJShellのススメ https://news.mynavi.jp/techplus/article/imajava-3/ コンパイラ型の処理系だと、当然コンパイルせな「結果が分からん」し、部品を作ってる筈なのに、「部品だけ」だと実行しても何も表示されないんで、部品なのにソースにprintlnを仕込んだりして、開発効率が悪かったんだけど、JavaはJShellと言う「インタプリタ」を提供しはじめた為、部品をインタプリタ上で実行して結果を見て判断したり、あるいは、「上手く行くかどうか分からない」コードをJShell上で実行して、上手く行った分だけ書いてるソースコードにコピペして・・・と言うような柔軟な開発が出来るようになった。 んで、上の記事でも書いてるけど、インタプリタの構成法を「REPL(Read-Evaluate-Print-Loop)」と言う。上で挙げた「読み込み部」「評価器」「表示部」と全く同じ部品構成だ。それを組み合わせてLoopさせる。 極論、理論的には、全てのソフトウェアはインタプリタの延長線上にあるんだ。逆に言うと、インタプリタの構成法がソフトウェア作成の基礎だ、ってこった。 繰り返すけど、#5氏はコンピュータサイエンス的に物凄く重要な示唆をしている。そこが大枠で、「手続き型プログラミング」とか「オブジェクト指向」と言うプログラミングパラダイムの区分よりも大きな枠組みなんだ。 多分、一つの考え方として、「Javaによるオブジェクト指向がどーの」と言うより、「Read、Eval、Print」と言うパーツ区分をどうやってJavaのオブジェクト指向で組むのか、って考え方の方が「木を見て森を見ず」にならんでエエかもしんない。 例えば古い記事だけど、こういうのが参考になるかもしんない。 やさしい Lisp の作り方 by Java: https://web.archive.org/web/20161014011854/http://www.oki-osk.jp/esc/go.html ここでは、実際にJavaでLispと呼ばれるプログラミング言語の簡単な実装方法が紹介されている。 Lisp: https://ja.wikipedia.org/wiki/LISP

  • ddtddtddt
  • ベストアンサー率56% (179/319)
回答No.5

 Javaは良く知りませんが・・・。  #4さんの仰る「構造化プログラミング」は、「手続き志向の構造化」だと思います。ここで手続きとは「関数」の事で、言ってしまえば計算処理の事です。手続き志向なので、「関数」が主で「ユーザー定義型」は従です。このやり方は今では当たり前になってると思います。  一方「構造化プログラミング」には、「データ志向の構造化」ってのもありました。データ志向なので、「ユーザー定義型」が主で「関数」は従となり、その代表はデータベースです。  この二つは、自分の意見では徹底的に相性が悪かった。何故なら手続き志向は処理優先で、「ユーザー定義型」を許容はするものの、その運用については全く考えられていなかったから。データ志向はデータ志向で、処理の運用は全く無視されたから。例えばデータベースはデータの更新と保存とに特化し、得たデータをどう処理するかは別の話として扱われます。  オブジェクト志向の一つの説明としては、「手続き志向」と「データ志向」の良いとこどり、という話があります。形式としてはプログラム単位はデータ(ユーザー定義型)になる。ただしこのデータは、自分自身を処理する関数を必要なだけ自由に持てる。感じとしては、「データを処理したいなら、そのデータの事を一番良く知ってる、そのデータ自身に頼め!」という事になります。データ自身とはオブジェクトの事です。この感じを推し進めると、オブジェクトとは「物」というより、「処理の実行者」という感じです。  オブジェクト志向言語のオブジェクトには、あまり注目されませんが必ずコンストラクター(初期化関数)を付けるのが作法になってます。それを念頭に、プログラムが何をするかという事を考えると、「人間から入力を受け取り、入力を処理し、処理結果を出力する」ってのがおよそやる事の全てです。以下、VBでの用語と表記です。   '入力受け取り   Dim Inputter as Input = New Input()   Dim Input_Data as InputData = Inputter.Data   '処理   Dim Runner as Run = New Run(Input_Data)   Dim Run_Data as RunData = Runner.Data   '処理結果出力   Dim Outputter as Output = New Output(Run_Data)  Input,Run,Outputは、入力受け取り,処理,処理結果出力に対応するクラスです。VBではコンストラクターはNew演算子になります。Inputter,Runner,Outputterは、Input,Run,Outputクラスのインスタンス(オブジェクト)で、入力,処理,出力を行う「実行者」。Inputクラスのコンストラクターが引数を持たないのは、入力用のマン・マシンインターフェイスや入力ファイルを司る、低レベルオブジェクトと裏でつながってるのを想定したもので、そこはここでは明示しません。  「実行者」Inputterは、とにかく生成時に入力を受け取り、それを処理に適したInputData型に成型する。それを外部に公開するのが、.Data関数。  「処理実行者」Runnerは生成時にコンストラクターを通じて入力情報Input_Dataを受け取り、計算処理を行い、処理結果を出力に適したRunData型に成型する。それを外部に公開するのは、やはり .Data関数。  「出力実行者」Outputterは、同様に生成時にコンストラクターを通じてRun_Dataを受け取り、出力を行う。この実行者も、出力用のマン・マシンインターフェイスや出力ファイルに関わる、低レベルオブジェクトと裏でつながってるものとします。  以上のように、メインルーティンで変数定義を済ませた瞬間には、少なくともコード上では結果が出ているような事態、これが自分の思う理想的なオブジェクト志向プログラミングです。  もちろん上にあげた「実行者」は色々なクラスに依存したりしますし、各クラスの内臓をぶちまけたら、#4さんの仰るような「垂れ流し」の「スパゲッティー・コード」になってる事もしばしばでしょう(^^;)。  結局やる事はいっしょですから、どんな方法を使ってもコード量はそんなに変わらない(^^;)。

回答No.4

あー・・・う〜ん・・・・・・。 ぶっちゃけて言うと、Javaって言語でオブジェクト指向を学ぶのはムズいんだよね。 なんせJavaは「(いわゆる)オブジェクト指向を強要する」から。 「(いわゆる)オブジェクト指向を強要しない」言語(例えばC++とか?)だとちょっと離れてオブジェクト指向を見れるんで、ある程度「客観性」を得られるんだ。一歩引いて見られるから、ね。 一方、Javaだとオブジェクト指向が根幹になってる。ずっぽりハマってるわけだよ。だから客観的に見るのが難しいわけだ。なんせ、「オブジェクト指向」以外の方法でプログラミングが出来ない。だから「いまいちわかりません」からスタートすると、下手すればどこまでも「わからない」が続く事になる。 1970年前後に「構造化プログラミング」と言う方式が確立された。要は定式化した、って事なんだけど、それまでのプログラミング言語ってのは原則、処理をダラダラ書いてたのね。垂れ流しだ(笑)。今で言うとアドベンチャーゲームのプログラムみたいになってたのよ(笑)。逐次処理とジャンプしかない(笑)。 一方、構造化プログラミング、ってのは次の2つを二本柱としたプログラミング方策、って事だよな。 ・プログラムを構成する「単位」を関数とする。 ・豊富なデータ型を備えた上にユーザーに新しいデータ型定義の自由を与える(ユーザー定義型) ザックリ言うと、これが構造化プログラミングだ。 ただし、ここには主従関係があって、構造化プログラミングでは「関数」が主で「ユーザー定義型」ってのは従って考えていい。豊富な型やユーザー定義型が単一で存在して「それを処理する為に」関数がある。そういう方針でプログラムを組み立てて行くわけだな。 ところが(正確に言うとオリジナルの登場はもっと早いんだけど)、この主従関係を「逆」にした方がエエんちゃうの?ってプログラミング・パラダイムが出てきたわけだ。 つまり、 ・豊富なデータ型があり、ユーザー定義型がある。 ・関数はあくまでデータ型操作としての「補助」の役目を果たす。 => メソッド データが主で関数が従、と。構造化プログラミングだとプログラムを構成する「単位」は関数だったんだけど、そうじゃなくってプログラムを構成する「単位」をデータにしよう、と。 平たく言うと、これを「オブジェクト指向」って言うんだ。 んで、C++も基本は構造化プログラミングのC言語を土台としてるんだけど、一方C++ってのが持ってる「オブジェクト指向」部分ってのはCのユーザー定義型、「構造体」(+ typedef)の「拡張」なんだよね。だからC++のユーザーでCを経由してきた人はC++の「クラス」を「構造体の便利な拡張」程度に捉えていて、あまりオブジェクト指向にビビらないんだ。と言うより「殆ど」Cで書いて「部分的に」オブジェクト指向で書く、的な自由なプログラミングをやってる人が多いんじゃないかな。 その辺がJavaとは違う。そしてJavaは「オブジェクト指向を強要する」為、説明がイマイチ分かりづらくなってんだよ。なんせJavaはプログラミング・ニュービーにもアピールしよう、って戦略を取ってたんで、「オブジェクト指向」を説明しよう、って比喩が逆に分かりづらかったりすんだよな(笑)。なんせユーザー定義型である「構造体」(+ typedef)とかPascalで言う「レコード型」を知らない人相手に説明せなアカン、と。 だから大体、「オブジェクト指向のワケの分からん説明」ってのはJava発祥だ(笑)。 繰り返すけど、オブジェクト指向ってのは「データ型」を中心としてプログラムを組もう、って言う「流派」だ。そしてその「データ型」はユーザー定義型、つまり貴方がデータ型を「自在に作る」と言う事を前提にしてる。そしてJavaでのユーザー定義型定義に使うのを「クラス」と言う。 O.K.? > 本ではオブジェクトは「物」と記載していますが、いまいちわかりません。 うん、分かんねぇよな(笑)。マトモな訳語作れよ、とか僕も思う(笑)。ピンとこない。 ええと、だな。オブジェクトってのは「データ」って考えていいんだけど、ちと補足が必要かも。 例えばだな。C言語みたいな低レベルなプログラミング言語だと、誤解を畏れずに言うと、「データ型」ってのが無いんだよ。いや、一つだけC言語が持ってるデータ型があって、それは「数値」なんだ。ところが、C言語ってのは数値以外何もねぇのな。 じゃあ、C言語では「文字列」とかどうなってんの?って話になるんだけど、極論それも数値だ。ホント数値しかなくって、やっぱり言っちゃえば「データ型」ってのが無いんだ。深くツッコむと文字列と数値に差が無くなっちゃうんだ。 C言語は低レベルで動くんで、ハードウェアに密接に関係するように設計されてるんで、この方針はそういうレイヤーでは「是」なのね。 一方、一般的な高級言語では「数値は数値以外の何物でもない」「文字は文字以外の何物でもない」「文字列は文字列以外の何物でもない」って言う風にしたいわけ。いくら低レベルレイヤーでは「全ては数値です」でもその影響を高級言語が動いてるレベルまで持ち込みたくない。そういうのを「抽象化」っつーんだけど、単にデータと言うよりは「××は××以外の何物でもない」ってのを主張する際に「オブジェクト」って言い回しをするわけよ。 つまり、(C/C++以上の)「高級言語のレイヤー」ではデータ型を「オブジェクト」と呼称するケースが多い。Javaなんかの文字列も実装がどうなってるのか、って深い部分ではさておき、「文字列オブジェクト」って言った時点で「文字列以外の何物でもない」って事を主張してるわけだ。 それが一般的な(C/C++以外の)高級言語での言い回しなんじゃないかな。 さて、と言うわけで、オブジェクト指向は「データの、データによる、データのための」プログラミング方策、って事が分かると思う。 っつーかさ、概念的な?トリビアルな部分だと多分誰も悩まないんだよな。「あ、そう」って終わっちゃう(笑)。 むしろ、「オブジェクト指向による実際的なプログラミング方法」の方を悩まない?オブジェクト指向って言う「枠組み」はともかくとして、「じゃあどんな風に"プログラムを"データで分割して仕上げるねん」って話だよな。 例えばJava的な「よくある比喩」として「現実世界を反映する」とか言うわけよ。 いや、それってホント方策として大丈夫か?ってのは山程あるんだ(笑)。マジでそれに解決策ってあんの?的な。 例えば貴方の要求に従って「人」「りんご」で考えよう。 人をクラスを使って定義する、って事は上でも書いたけど「人って名前のユーザー定義型を作った」って事だ。これにより人は人であってそれ以外ではない、新しい「型」として定義されたわけだ。 りんごをクラスを使って定義する、って事は上でも書いたけど「りんごって名前のユーザー定義型を作った」って事だ。これによりりんごはりんごであってそれ以外ではない、新しい「型」として定義されたわけだ。 ここまではいい?多分大丈夫だとは思うんだけど。 問題はメソッド、あるいはメンバ関数って呼ばれるヤツなんだよな。構造化プログラミングでは「ユーザー定義型」対象だろうと「外部から」関数が作用出来た。 一方、通常良くあるオブジェクト指向だと、データ型自体が自らを操作出来る関数を「内部に持つ」。これをメソッドとかメンバ関数って呼ぶわけだけど。 多分ここで悩むんだよな。何をどう実装すれば「簡単になるのか」。 繰り返すけど、Java的なオブジェクト指向の解説だと、「世の中はモノで溢れています。よってオブジェクト指向は現実を簡単に抽象化出来ます」とか言ってんだけどさ(笑)。 ・人はりんごを食う。 ・りんごは人に食われる。 前者はりんごを引数にしたメソッドを書けば解決する。 後者は人を引数にしたメソッドを書けば解決する。 いや、理屈はその通りなんだけど、「そんな風に実装して嬉しいか?」って話がどうしても出てくる(笑)。現実世界を抽象化?それってもっと「ややこしい」事にならんだろうか。 他にも、例えばりんごを実装する前に抽象クラス「果物」を作ってりんごは「果物」を継承して作るべきじゃないか。 人は霊長類なんで、抽象クラス「霊長類」をまずは作ってそれを継承して作るべきじゃないか。 いや、ホンマ「抽象クラスをまずは作って・・・」ってのも良く見かける。でも抽象クラスって考えてみれば「どこまでも遡れる」のよ。上の例でも「果物」クラスや「霊長類」クラスは「生き物」クラスを継承すべきじゃないか・・・とか考えていくと夜も眠れない(笑)。眠れたとしても翌朝「Eureka!」とか言いながら哲学者になってたり、あるいは「神の声が聞こえます」とか言いながら新興宗教の開祖になってるかもしんない。 イカンよな、それじゃ(笑)。 つまり、現実的には「どっかで打ち切らないとならない」んだけど、実は僕自身はそういう「ノウハウ」ってのは見たことも聞いたこともないんだよ。あくまで「現場の判断」と言う「理屈じゃない」トコが決定してんのね。 と言うわけで。 残念ながら「Javaのオブジェクト指向の機能を知る」ってのと「一般的なオブジェクト指向の考え方を知る」ってのはステージが違う話なんだよな。 Javaは電卓だ。電卓の「使い方」は説明可能だけど、「四則演算のコンセプトが分かる」ってのとは必ずしも一致せん、って言えば分かるかな?そういうレベルの話になるんだよ。

  • kzr260v2
  • ベストアンサー率48% (852/1775)
回答No.3

開発環境のインストールはお済みということで良いでしょうか。 オブジェクト指向をイメージしやすくなる訓練としては、ユーザーインターフェース(UI)について、サンプルコードを作成する方法があります。例えば、テキストボックスなどの基本クラスを派生させて、特定の数値のみ入力できるテキストボックスを作ったりです。まずはこのような簡単なコードから始めてみることをご検討ください。自然と基本クラスで何をやっているかや、さらに基本となるクラスの関係などがイメージでき、オブジェクト指向プログラミングでなにをさせたいか分かるかもしれません。 ※ もし、オブジェクト指向の考え方をリンゴや人などで説明できたとしても、それがプログラミングコードへの活用にはつながりにくいと、私は思います。プログラミングコードは「物」ではありませんので、親和性が低い印象です。 それらに比べ、テキストボックスなどUIのコンポーネントは、プログラムの実行時に【実際に表示】されますから、ある種、プログラム内での「物」に近いです。そして、UIの基本クラスはライブラリに用意されているものが多数あるので、自作の派生クラスのイメージがつきやすいです。 ※ 難しいのは、独自のクラスです。例えば「医療レセプトクラス」のようなライブラリに基本クラスが存在しないものを新規に作る場合です。データベースへの読み書きも含めた機能を持たせるかもしくは別に設計するか、歯科や内科や外科など派生クラスが作成できるよう基本クラスにどの程度機能を実装するか、などなど検討する余地が沢山ありすぎるのです。このあたりは、「実際に作成したコードがエンドユーザーに使われ、動作変更要請による修正を何度も経験した」あたりで得られやすいようです。 なにも実績が無い1番最初は妥協して、医療レセプトクラスなどは作らず、メイン内にグローバル関数を作りまくる、なんてオブジェクト指向を無視したやり方もなくはないと思います。業務に必要な関数の実装が終わったあと、次期バージョンでクラス化を検討します。 とはいえ、このあたりの「基本クラスにどこまで実装するか」や「基本クラスに【あえて】実装させず派生クラスで実装させる」は、UIで独自クラスを派生させると、イメージつきやすいと思います。 以上、わかりにくかったり、参考にならなかったらごめんなさい。

  • Kaneyan-R
  • ベストアンサー率42% (1340/3126)
回答No.2

ざっくり言います。 「一人でやる」か「みんなでやる」かの違い。 従来のプログラムは、メインプログラム内で読み書き保存など全てのことを処理していました。 オブジェクト思考プログラムでは、このプログラムは「読み込むだけ」、このプログラムは「処理するだけ」と、個々のプログラムは別々のことを行っていて、メインプログラムはその仲介をして工程管理するだけと言う存在になりました。 つまり「一人で全部の仕事を行っていたものを分業化した」と言うことです。 ボタンのプログラムなら常にボタンの状態を監視していて、「マウスが重なった」とか、「ボタンが押された」とか、「クリックされた」とかの情報を読み取り、メインプログラムから「クリックされたら教えて」とか「押されたらこれやっといて」と言われたら、その時だけ処理を行います。

  • garo1970
  • ベストアンサー率54% (60/111)
回答No.1

では例えで表現しますので、細かい齟齬はありますがご勘弁を。 演劇を作る場面で例えると、 ⚫︎手続き型プログラミング(オブジェクト指向の対義の手法)は 脚本を書くようなもので、時間に沿って誰が何を言って、どう動いて・・・ ということを台本に逐一全てを書いていく感じです。 ⚫︎一方、オブジェクト指向というのは オブジェクト(物)というのはこの例えの場合 役者一人一人、舞台の装置、小道具などがこれに当たります。 全体の脚本というのは書かず (脚本家(プログラマー)はこうしたいというプランはあるけれど) 役者には脚本は与えられないので、その代わりに "あなたは28歳・男性・秋田県出身・気が弱くて・・・"というようなプロフィールと 「こういう状況になったらこうして」という命令だけを指定する こうすることで自動的に意図した演劇が出来上がるという感じです。

関連するQ&A