最近、PHP5 インターフェイスを学習する過程で困難に遭遇しました。本には多重継承を実装する方法と書かれていましたが、実装方法がまだわかりません。インターネット上には PHP インターフェースに関する情報がほとんどないので、Java について調べてみましたが、基本的には同じです。 「Java をわかりやすくする (インターフェイスと継承)」の記事を読んで、私が最初から誤解していたことに気づきました。いわゆる多重継承とは、クラスがインターフェイスを継承するのではなく、クラスを継承するインターフェイスを指します。
この記事では、OO の抽象化について言及していました。「抽象化とは画像の部分を削除することです」という一文がとても鮮やかでした。抽象化について考えるとき、私はいつも理解するのが難しいと思っていました。はい、これはまさにインターフェイスと抽象クラスが行うことです。
この記事には、以下に示すように、私にとって非常に有益な視点が他にもたくさんあります。
OO の本質はオブジェクトの抽象化であると私は考えています。
インターフェースの機能は、一言で言えば、クラスのタイプをマークすることです。異なるタイプのクラスを異なるインターフェイスに割り当てると、クラスをより適切に管理できます。
継承のポイントも抽象化であり、コードの再利用ではありません。
この記事を読んだ後、インターフェイス、抽象クラス、継承の適用方法を基本的に理解しました。
原文は次のとおりです。
Java の明確化 (インターフェイスと継承) コンピュータ サイエンス学部の大学院 2 年生である兄が私と Java について話し合ったとき、いくつかの質問はすべてインターフェイスの使用法に関するものでした。なぜインターフェースを使用するのでしょうか?インターフェイスをいつ使用する必要がありますか? Java を使用して SQL Server に接続する方法や、J2EE アプリケーションを開発する方法について質問されなくてよかったと思います。このような質問は致命的であるため、避けるべきです。今年、コンピュータサイエンス学部には J2ME に関する卒業プロジェクトがあります。このテーマを選択した学生たちは、5 月末の時点でまだ java.util.* パッケージを勉強していました。
ほとんどの人は、インターフェイスの目的は多重継承を置き換えることであると信じています。ご存知のとおり、Java には C++ のような多重継承メカニズムはありませんが、複数のインターフェイスを実装できます。実際、これは突飛です。インターフェイスと継承はまったく別のものです。インターフェイスには多重継承を置き換える機能はなく、そのような義務もありません。インターフェースの機能は、一言で言えば、クラスのタイプをマークすることです。異なるタイプのクラスを異なるインターフェイスに割り当てると、クラスをより適切に管理できます。 OO の本質はオブジェクトの抽象化であり、インターフェイスがこれを最もよく体現していると思います。なぜ抽象機能を持つ言語 (C++、Java、C# など) のデザイン パターンについてのみ説明するかというと、デザイン パターンが研究するのは実際に合理的に抽象化する方法だからです。 (カウボーイの有名な言葉に「抽象化とはイメージの部分を取り除くことだ」というものがあります。これは冗談のようですが、実際は本当です)。
最も基本的なデザイン パターンは Factory パターンです。私が最近作成した非常に単純なアプリケーションでは、プログラムを複数のデータベース間で移植できるように最善を尽くしたいと考えていました。もちろん、これには SQL の互換性を含めた多くの問題が含まれます。異なる DBMS からの接続は頭痛の種です。まず問題を単純化し、異なるデータベースを接続する方法のみを検討することもできます。
Mysql.java、SQLServer.java、Oracle.java、DB2.java という多くのクラスがあり、それらはそれぞれ異なるデータベースに接続し、一律に Connection オブジェクトを返し、すべてに接続を閉じるための close メソッドがあるとします。 DBMS に別のクラスを選択するだけで、それを使用できるようになります。しかし、ユーザーはどのデータベースを使用するのでしょうか?わかりませんが、私が望んでいるのは、彼のニーズを満たすためにコードの変更をできるだけ少なくすることです。次のインターフェイスを抽象化できます。
パッケージ org.bromon.test;
パブリックインターフェースDB
{
java.sql.Connection openDB(文字列 URL,文字列ユーザー,文字列パスワード);
void close();
、
意味のあるコードはありません。特定のコードは、このインターフェイスを実装するクラス (Mysql.java など) によって提供されます
。
インポート java.sql.*;
パブリッククラスMysqlはDBを実装します
{
プライベート文字列 url="jdbc:mysql:localhost:3306/test";
プライベート文字列ユーザー = "ルート";
プライベート文字列パスワード=””;
プライベート接続 conn;
public Connection openDB(url,user,password)
{
//データベースに接続するコード}
public void close()
{
//データベースを閉じる}
、
もちろん Oracle.java などです。アプリケーションでは、これらのクラスを分類します。
org.bromon.test.DB
myDB を使用してデータベースを操作します。私が実際に使用しているクラスは、いわゆる「オープン-クローズド」原則です。しかし、問題は、インターフェイスをインスタンス化できないことです (myDB=new DB())。このようなコードは完全に間違っており、myDB=new Mysql() または myDB=new Oracle() しか実行できません。申し訳ありませんが、インターフェイスを使用しても、どのクラスをインスタンス化するかを指定する必要があります。したがって、ファクトリーが必要です。
package org.bromon.test;
パブリック クラス DBFactory
{
パブリック静的 DB 接続 getConn()
{
Return(new Mysql());
}
、
インスタンス化コードは次のようになります。 myDB=DBFactory.getConn();
これは23のモードの中で最も基本的な通常のファクトリ(Factory)であり、ファクトリクラスはどのクラスを具体的にインスタンス化するかを担当し、その他のプログラムロジックはDBインターフェース上で動作します。これは「インターフェースのプログラミング」です。責任はファクトリ クラスに渡されています。もちろん、ファクトリ インターフェイスを定義し続けて、抽象ファクトリに進化することもできます。
他のプログラムがデータベースに接続したい場合、インターフェイスは、ファクトリ クラスがどのように変更されるかに関係なく、DB オブジェクトを構築するだけで済みます。これがインターフェイスの本質、つまり抽象化です。
言うまでもなく、継承の概念は理解しやすいです。なぜ継承するのか?コードを再利用したいからですか?これは決して理由ではありません。継承のポイントはコードの再利用ではなく、抽象化です。オブジェクト A に run() メソッドがある場合、オブジェクト B にもこのメソッドが必要なので、クラス B の拡張 A を使用する人がいます。これは無謀なアプローチです。 B で A をインスタンス化し、A の Run() メソッドを呼び出した場合、同じ目的を達成できますか?次のように:
クラスB
{
A a=新しいA();
a.run();
、
クラスの集約を使用してコードを再利用することです。これは委任モデルのプロトタイプであり、GoF が常に提唱している手法です。
それでは、継承のポイントは何でしょうか?実際、これは歴史的な理由によって発生します。元の OO 言語には継承のみがあり、インターフェイスがなかったため、抽象化は継承によってのみ実現できました。継承の本来の目的は抽象化であり、コードの再利用ではないことに注意してください (ただし、継承にもこれはあります)。これは、多くの悪い Java 書籍の最も重大な間違いの 1 つです。私は、それらが引き起こした影を完全に取り除くことができませんでした。特に入門書は有害です。継承を使用する必要があるのはどのような場合ですか?抽象クラスでのみ使用し、他の状況では使用しないようにしてください。抽象クラスはインスタンス化できないため、テンプレートのみが提供されますが、これが問題を示しています。
ソフトウェア開発、特に C++ プログラマにおける諸悪の根源は、コードの再利用ではなくコードの重複と、継承の誤用です。 Java で多重継承を禁止する目的は、継承の悪用を止めることです。これは非常に賢明なアプローチですが、多くの人はそれを理解していません。 Java はデザインをよりよく反映できるので、これが私が魅力を感じている理由の 1 つです。