Javaで、親クラスの参照とサブクラスのオブジェクトを作成する必要があるのはなぜですか? これで何を達成できますか?明白な答えはポリモーフィズムですが、その範囲は何ですか? リアルタイムでどのように役立ちますか? Javaを学んでいるときにこれに出くわしました。
2 に答える
あなたの例では、親クラス参照を使用することで、渡されるリストの特定のタイプを気にせずに、任意の種類のリストを取り、それを操作するメソッドを作成できます。
一方、サブクラスは実際の実装を指定するため、メソッドのユーザーは、要件に最も効率的または適切なリストを選択できます。
List の合計を計算するメソッドを作成するとします。
int sum(List<Integer> input);
ここで、メソッドの 1 人のユーザーが高速ランダム アクセスを気にするリストを持っているとします。そのユーザーは ArrayList を作成し、別のユーザーは自分のリストを頻繁にスプライスして結合したいので、代わりに LinkedList を使用します。
これらの両方のユーザーが sum メソッドを使用できるようになりました。
ポリモーフィズムは実生活でどのように役立ちますか?
コードの柔軟性を高めて、さまざまな引数や実装に対応できます。
たとえば、次の方法を考えることができます。
void foo(ArrayList<T> arg) {
for (T t : arg) {
// do something
}
}
このメソッドを ArrayList のみを受け入れるように制限する必要があるでしょうか? 結局のところ、そこで使用している関数は、LinkedList または Set で同様に実行できます。代わりに次のように記述すれば、さらに機能的になります。
void foo(Iterable<T> arg) {
for (T t : arg) {
// do something
}
}
同様に、次のように記述します。
ArrayList<T> arg = new ArrayList<T>();
これは、arg で使用したいメソッドが ArrayList でしか利用できない場合にのみ役立ちます。必要なメソッドが ArrayList のスーパークラスで宣言されている場合、次のように変更することでコードをより柔軟にすることができます。
Collection<T> arg = new ArrayList<T>();
そして、arg を実際にソートする必要があると判断した場合は、非常に簡単に次のように変更できます。
Collection<T> arg = new PriorityQueue<T>();
foo() は ArrayList を受け入れるのと同じくらい喜んで PriorityQueue を受け入れるため、コードの他の部分を壊すことはありません。サブクラスの特定の実装の詳細に依存するのをやめると、多くのことを非常に迅速に変更できます。
コメントで述べたように、非常に単純な例から抜け出すと、より強力になります。データベースとやり取りするアプリケーションがあるとします。私たちのデータベースが MySQL の場合、非常に具体的な MySQL コードを書くことに夢中になるかもしれません:
MySQL db = new MySQL();
int results = db.mySqlExecute("SELECT count(*) FROM names WHERE firstname = 'Bobby';");
大規模なアプリケーションで多くのことを行った後、コードは MySQL と完全に切り離すことができず、PostgreSQL などの別のデータベース システムを実装することはできません。代わりに次のように書くと:
DataBase db = new MySQL();
int results = db.getCount("names", "firstname = 'Bobby'");
最初の行を次のように簡単に変更できます
DataBase db = new PostgreSQL();
あなたのコードは、たった 1 つの簡単な変更でうまく機能します。これがポリモーフィズムの力です。単一の実装に縛られないのです。