5

Shape基本クラスとさまざまな派生型があるとしますCircle

これを書くことによって、新しいオブジェクトを作成するときにすぐそこにアップキャストする理由はありますか?

Shape s = new Circle();

これの代わりに:

Circle s = new Circle();

そしてs、これらの2つのステートメントのそれぞれによって作成されたオブジェクトは、互いに何らかの形で異なりますか?

4

7 に答える 7

3

Shape s = new Circle();最初の例(つまり)には、Shapeが抽象または具象の基本クラスである場合でも、「インターフェイスへのコーディング」と同じ利点があると主張できます。したがって、たとえば、Circleに固有のメソッドではなく、Shapeで定義されたメソッドのみを使用する場合は、たとえば1行のコードを変更するだけで、使用している実装をSquareに簡単に変更できますShape s = new Square();

オブジェクトは両方の例で同じです。最初のオプションがより適切であると見なすことができる理由は、よりスタイル的なものです。インターフェイスにコーディングすると、コードベースをより簡単に拡張および変更できるようになります。

于 2011-03-29T08:58:40.367 に答える
3

これらの2つのステートメントは、JVMに関する限り、同じオブジェクトを生成します。基本クラスまたはインターフェースにのみオブジェクトを使用することを計画していることを示すのは珍しいことではありません。たとえば、これは一般的です。

List<String> list = new ArrayList<String>();

一般的には良い考えではありませんが、それが1つであることが確実にわかっている場合は、にShape戻すことができます。たとえば、次のように戻すことができます。CircleShape sCircle c

if (s instanceof Circle) {
    Circle c = (Circle) s;
    // handle Circle case
}
于 2011-03-29T08:53:43.473 に答える
2

インスタンス化されたオブジェクトはまったく同じです。

アップキャストの結果は次のとおりです。

  1. 保存中の一般化:異なる特殊なタイプのすべてのオブジェクトが同じインターフェースとして脅かされる可能性があり、データ構造に一緒に保存される可能性があります。(@ WhiteFang34が指摘したように:リスト<形状>)
  2. オブジェクトメソッドにアクセスする際の一般化:クライアントクラスは、実際のタイプを知らなくてもShapeのメソッドを呼び出すことができます(通常、ファクトリを使用して、共通インターフェイスShapeを返すオブジェクトを作成できるため、クライアントクラスはオブジェクトの実際のタイプを認識しませんが、 Shapeのインターフェースメソッドが公開されています)
于 2011-03-29T09:07:28.333 に答える
1

あなたの質問に答えると、2つのオブジェクトはまったく同じです。両方の参照が同じオブジェクトを指す可能性があります。

Circle c = new Circle();
Shape s = c;

インターフェイスにコーディングすると、コードへの影響を最小限に抑えて実装クラスを変更できます。あなたがこれを持っているとしましょう:

Set<String> names = new HashSet<String>();         // using Set reference not HashSet
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

これで要件が変わり、名前をアルファベット順に印刷する必要があります。つまり、TreeSetの代わりにHashSetを使用します。インターフェイスにコーディングし、HashSetクラスに固有のメソッドを使用していないため、変更する必要があるのは1行だけです。

Set<String> names = new TreeSet<String>();   // the only line of code that changes
names.add("Frank");
names.add("John");
names.add("Larry");

for(String name: names) {
    System.out.println(name + " is in the team");
}

インターフェイスでは、依存性注入を使用することもできます。これにより、コードを記述した時点では存在しない可能性のあるクラスを使用できます。

http://en.wikipedia.org/wiki/Dependency_injection

于 2011-03-29T09:30:43.940 に答える
0

いいえ、オブジェクト自体に違いはありません。コンパイラーが見ていると考えるものだけが異なります(たとえば、どのメソッドが使用可能か)。

このようなキャストを行う理由の1つは、オブジェクトをどのように処理するかを表現することです(代わりに、別の派生クラスを簡単に挿入できるようにするため)。

于 2011-03-29T08:56:20.527 に答える
0

@WhiteFang34の言うことに同意します。

このインターフェースへのコーディングを参照してください。 これはあなたを助けるかもしれません。

于 2011-03-29T08:58:13.273 に答える
-2

Circle s = new Circle();
ここで、オブジェクトはクラスCricleを参照しています

形状s=new Circle(); ここでは、インターフェースを参照するオブジェクト

どちらも同じです。

于 2011-03-29T08:56:50.240 に答える