Javaのオブジェクト指向

Javaは、オブジェクト指向プログラミングの、代表のように言われていますが、
さてさて、
 オブジェクト指向
とは???
一言に、オブジェクト指向と言いましても、
Java言語以外でも、使われています。
そして、私には、違いが判りません。
ですから、
 Java言語特有なObject思考
と言い換えたほうが、正確な、言い方ですね。
(もちろん、Javaが生まれる前の言語の影響はあると思われます)

そして、その内容は、ちょっと恥ずかしいのですが、
いま改めて、学習しなおした感じです。

ということで、本題に入ります。
また、まったく、Javaの知識がない方には、申し訳ありませんが、
ちんぷんかんぷん、だと思われます。
そのあたりについては、サポートできるかは、わかりませんが、
以降、Javaの文法についても、ページを書いていこうと思っていますので、
そちらを先に読めば、ピンとくるようになるかもしれないです。


3-1. Encapsulation(カプセル化)
カプセル化というのは、シールドな感じのことです。
または、核シェルターという時の、
シェルターな感じでしょうか?
つまり、複雑で長いプログラムを書いていくとき、
同じような、名前の変数や、メソッドがあった場合、、
classによって、分類されていると、
classのオブジェクトや、class名(クラスメソッド)を使って、
アクセスするので、もしかして、「とんでもない 変数 や メソッド」を、
間違って、呼ば(call)ないようにできることです。
ただし、これは、Javaで書けば、だれでも得られる恩恵ですが、
さらに、高度なやり方
(オブジェクト指向に慣れている人には常識のようですが)
が、あるようです。

右のPDFは、Javaコードの、「イメージコード」ですが、
実際に実行する前に見てみましょう。
PrivateNumberクラス の、
 privateな変数:secret
に、アクセスするために、2つの方法をとっています。
一つ目は、Go1クラスで、
 PrivateNumberクラスのオブジェクトを作り、
 そのオブジェクトから、インスタンス変数に、
 直接アクセスしようとしています。
変数が、publicであれば、問題なく、アクセスできるのですが、
privateな変数なので、アクセスできないように、
守られているのです。

そこで、Go2クラスでは、
 PrivateNumberクラス の、
 publicメソッド(publicなので、アクセスできます)
 を使って、アクセスすることに、成功します。

実際の、Javaコードを、使って、実験してみるとこうなります。

ということですが、
経験の浅い私には、
「ここまでする?」という気持ちもややありますが、
このやり方を、覚えるためにも、Javaをある程度、マスターした際には、
このやり方で、しばらく通そうと思っています。
きっと、これは、入門書には、書かれていませんが、
(私が忘れているだけかもしれませんが)
本当に、実用アプリを、作ろうとした場合、
必須な、ことだと思われます。


3-2. Inheritance(継承)
では、2つの目の話題
 継承(inheritance)
についてお話します。

簡単に言うと、
 動物の遺伝
が、モデルになっていると考えていいでしょう。
名前も、親クラス(Parent)子供クラス(Child)
のように言っています。
ただ、これも、理解しやすいからそう言っているわけで、
そんなに完璧に、遺伝のメカニズムを、取り入れるのは、無理です。
それに、もし、「突然変異」など起こされたら、
プログラムは、破壊されてしまいます。

それは、さておき、
 継承 が、あると、どんないいことがあるのか?
について、見ていきましょう。

1.
親クラスを利用すれば(extendsキーワード)、
最低限の、変数、メソッドを、宣言すればよい。

2.
階層的な分類 により、
全体像および、個々のクラス を、とても、理解しやすくできる。

つまり、下の層に行くほど、具体的になるので、
変数や、メソッドを、増やしていくわけなのですが、
その流れが、一直線になっているので、
とても、覚えやすい/理解しやすい わけなのです。
もし、この流れが無く、例えば、普通の車クラス と、高級車クラス 
を、別々に、定義するとすれば(クラスを設計するとすれば)、
高級車クラスには、先に挙げた、変数だけでは、きっと足りないから、
とても、たくさん定義しなくては、なりません。
また、親クラスを継承する場合は、その 変数/メソッド を、
無視できますが/書かなくて済みますが、それを、
全て書いていたら、それだけで大変ですね。
また、この流れが無いと、概要を、理解するのも大変そうです。

では、試しに、このコードイメージを、実際に、
Javaコード にして、DeluxeCarクラス が、
 いくつの変数
を、持っているか確認しましょう。
これが、そのソースコード と、実行結果です。

つまり、DeluxeCarクラス 内では、1つしか変数を定義していないのに、
継承(extendsキーワード)したことにより、
 5つの変数
を、持っていることがわかります。

ところで、ここまで、書いてみての感想ですが、
よく、
 オブジェクト指向 は、難しい
みたいに言われていますが、
その原因は、その「オブジェクト指向」は、
 オブジェクト指向という名前からは想像できない特徴
にあるのだということが、わかりました。
実際私も、多くのことを学びました。
とかく、オブジェクト指向と言うと、
 現実世界の反映
が、話題になりますが、また、たしかに、それは、
とても有効な方法だと思いますが、
それは、
 オブジェクト指向のやり方の
 一つに過ぎない
ということが、再認識できました。

オブジェクト指向は、簡単ではないようです。

今2つのポイントを述べましたが、
「オブジェクト指向という命名」からは、全然、
見当がつかないものですね。

では、最後の山場である、「多態性」について、考えてみましょう。


3-3. Polymorphism(多態性)
その前に、一言お断りしておきます:
 プログラムに使われている、英語の使い方は、
 多分に正しくない可能性があります。
 かと言って、正しい用法を調べている場合ではありません。
 よろしくお願いします。
 ついでに言えば、読みにくいのですが、
 ローマ字を使ってもいいのです。
また、後で学習する予定ですが、(文法を)
 特に、Javaの場合は、ルールがとても細かい
 、、、ただし、全てを、理解すれば、一貫性があることに気づく、、、
 です。
 私は、断然、IDEを使ったほうがいいと思います。
 最近の人気は、IntelliJのIDEですが、
 Eclipseは、日本語にも対応しているので、
 英語力のレベルが高くない限り、Eclipseのほうがいいと思います。
 アドバイスしてくれる日本語も、よくわからない時が多いですが、
 ないより100倍ましです。
 たった今も、この項目の例にするつもりのコードを書いていましたが、
 Eclipseが、
  interfaceの実装メソッドの可視性を下げてはいけません。
 と、言ってきました。
 (これでも、砕けた言い方にしています)
 はじめは、さっぱり言っていることが、分からなかったのですが、
 要は、メソッドに、public修飾子 を、付けろと、
 言っているのに気づきました。
 多分、IDEを使っていなかったら、数時間悩んだと思います。
 そして、解決したころには、疲れて、ダウンして、眠っていたでしょう。
 IDEの使い方などは、調べてください。
 おすすめの覚え方は、私の場合、Lyndaの、日本語版の、
 C講座で、使っていたので、それで少しづつ覚えました。
 多分予想ですが、Eclipseを使って、Javaを覚える本を使うのが、
 いいのではないかと、思います。
 
 今私が、主に、読んでいる本は、
  Java The Complete Reference, 9th Edition
   by Herbert Schildt
 という本ですが、この本は、素晴らしすぎます。
 また、Swingを、覚えようと思う場合、
  岩谷宏著、ひとつ上をゆく Javaの教科書
 が、おすすめです。
 Swingのシステムがよく説明されています。
 根本の理解がないと、応用が利きません。
 (サンプルコードとほとんど同じアプリしか作れない)
 だから、この本は素晴らしいです。
 今後は、JavaFXが主流になるようで、
 FXは、素晴らしいと思いますが、、
 学習にするにあたっては、アプリの作り方の「財産」が、
 たくさんある、Swingを、私は、まず覚えようと思っています。
 
 私は、ちょっと、Javaをなめていました。
 気合を入れて頑張って覚えるぞ!という決意です。
 ちょっと、public static void main(String[] args)
 が、今時長すぎないか?という、方も多いと思いますが、
 Javaは、きっとpayしてくれると、思っています。
 (pay … 割にあう)


では、本題に戻りましょう。
Polymorphism/多態性 とは、大体の意味は、
用語どおりでいいと思います。
しかし、用語 というのは、具体性に欠けます。
(コミュニケーションのための道具以上ではないということ)
Javaでの、「多態性」とは、
 interface/インターフェイス を使って、
  同じ名前のメソッド を、
  その実際に使われる、class/オブジェクト
  に、応じて、内容/アクション を変えて、
  使い分ける、、ことです。
その、利点/アドバンテージ は?、
 どのclassで、使われていても、
 メソッドを、
 抽象化して/大枠のアクションでひとくくりにして
 その具体的に使われるclassにおいて、
  ~と言う名前のinterfaceを、実装すれば、
 classを、素早く設計できる!
 ということが、分かっていること。
  / 戻り値・引数 は、既に実装済み.
  
自分で書いていても、集中力が、途切れそうなのですが、
ここで、イメージコード と、実例コード を、見てみましょう。

これを見て、もう一度、説明を読んでみてください。
すこし、理解しやすくなっていると、思います。

といいつつ、私も、分かったような、分からないような、ですが、
理解の一番の近道は、自分が信頼できる著者が書いた
作品/コード を、理解しながら、実際に書いて、実行してみる。
それを、たくさんたくさん、繰り返す。
これが、理解する、一番の近道だと思われます。


と、3つの、Javaのオブジェクト指向についてみてきました。
オブジェクト指向は、難しいですが、
が、しかし逆に、Javaでの、非オブジェクト指向的な書き方、、
つまり、main()メソッドに、全てのコードを、詰め込んだとしたら、、
それは、難しいというより、難しすぎるというべきでしょう。
コードのつながりを、理解しにくいコードのことを、
スパゲティコードと言いますが、オブジェクト指向は、それを、
避けるためにあるといえるでしょう。

Javaの一般的な評価は、
 堅実/バグを発生させにくい文法
だと思っていますが、あくまで、傾向であり、
やはり、プログラマが気を付けるべきことは、たくさんあると思います。
小さなプログラムのうちは、比較的、問題は起きにくいと思われますが、
大きく・複雑な、、つまり、実用的なプログラムにおいては、
やはり、
 カプセル化
などの推奨される方法は、守っていくべきだと思います。
なぜなら、private に、するか、public にするかは、
プログラマーの判断なので、コンパイラは、口を出すことができません。
特に、そういうところは、気を付けるべきでしょう。

また、「Javaの落とし穴」的な、本や、記事を、読むことも、
いいと思われます。

でも、考えてみてください。
Javaでさえ、これだけ、気を付ける必要があるのですから、
(実際に書いてみると、Eclipseに、警告ばかりされるので)
手続き型の言語では、もっと、大変だと思われます。
C言語は、「深く」学べば、コンピュータの仕組みにも、
近づけるようで、それは、利点だと思いますが。
あと、アルゴリズムを、学ぶのに、C や C++ で、
書かれた本が、とてもよさそうなので、気になりることはなります。

ちょっと話がずれました。

また、最近のJavaは、昔の評判とは、違い、「速い」、、
Cも驚く速さ?、、のようです。

とにかく、頑張って書いていきます。