5

これは以前に尋ねられたに違いないと確信していますが、同様の例が見つからないようです。私はポリモーフィズムとメソッドのオーバーロードをよく理解していますが、これは私を逃れるソリューションを備えた一見単純なシナリオです。

いくつかの派生クラスを持つ基本クラスがあるとしましょう。この例では形状を使用します

base Shape
derived Circle extends Shape
derived LineSeg extends Shape

現在、形状には、交差するかどうかを確認するために別の形状に対してテストする intersect(other) というメソッドがあります。ポリモーフィズムを使用すると、Circle、LineSeg などが独自の「交差」メソッドを実装する方法を簡単に確認できます。また、メソッドのオーバーロードを使用すると、必要なすべての組み合わせを簡単に実装できます。例えば、

Circle.intersect(LineSeg)
Circle.intersect(Circle)
LineSeg.intersect(Circle)

ここまでは順調ですね。

問題は、図形の中心的なリストを保持している場合、これを実行したいということです:

for some shape s
Foreach shape in Shapes
  if (s.intersect(shape)) - do something

メソッドのオーバーロードは、適切なパラメーターの型ではなく、基本型の Shape に一致する「交差」メソッドを選択するため、現在、これがどのように可能かはわかりません。タイプとダウンキャストをチェックするif-elseチェーンなしでこれを作成するにはどうすればよいですか?

ところで、私は Java を使用していますが、基本的な設計上の問題のように思われるため、Java が完全に関連しているかどうかはわかりません。とてもシンプルに見えますが、何が欠けていますか?

ありがとう!


以下で解決しました (ありがとう!)、詳細はこちらをご覧ください。基本的に、適切なメソッド (ビジター パターン?) を呼び出す派生クラスにコールバックを設定することで、"this" キーワードを使用して適切な交差メソッドを呼び出すことができます。これには適切な型が必要です。

4

3 に答える 3

4

私が最初に考えたのはビジター パターンでした。ほぼすべての Shape に 2 つのメソッドを与えます。1 つは私が呼び出しintersect(Shape)、もう 1 つdoIntersect()は Shape の種類ごとに 1 つのメソッドです。

次のようになります。

interface Shape {
    public abstract Intersection intersect(Shape other);

    public abstract Intersection doIntersect(Circle circle);

    public abstract Intersection doIntersect(LineSeg line);
}
class LineSeg implements Shape {
    @Override
    public Intersection intersect(Shape other) {
        return other.doIntersect(this);
    }

    Intersection doIntersect(Circle circle) {
        // Code to intersect with Circle
    }

    Intersection doIntersect(LineSeg other) {
       // Code to intersect with another Lineseg
    }
}

class Circle implements Shape {
    @Override
    public Intersection intersect(Shape other) {
        return other.doIntersect(this);
    }

    public Intersection doIntersect(Circle other) {
        // Code to intersect with another Circle
    }

    public Intersection doIntersect(LineSeg segment) {
        // Code to intersect with LineSeg
    }
}

doIntersect メソッドをパッケージ プライベートにするか、これらとは異なる名前を選択することもできます。

于 2013-05-20T00:04:53.803 に答える
0

ジェネリック Jdk5 を参照してください

シェイプ内の各シェイプについて <>

于 2013-05-20T00:16:00.623 に答える
0

形状クラスは抽象クラスでなければなりません。つまり、インスタンス化することはできません。派生クラス circle と lineseg のみがインスタンスを持ちます。intersect メソッドは形状が仮想である必要があるため、すべての形状をループすると、各形状の intersect メソッドが呼び出されます

public abstract class Shape {

    boolean intersect(Shape s);
}

public class Circle extends Shape {

    boolean intersect(Shape s) {
        ...
        if( s instanceOf Circle ) { 
           .... // Circle intersects cicrcle
        } else if( s instanceOf Lineseg ) {
           .... // Circle intersects Lneseg
        } else {
          throw RuntimeException("Unrecognized shape");
        }

    }

}

public class Lineseg extends Shape {

    boolean intersect(Shape s) {
        ...
        if( s instanceOf Circle ) { 
           .... // Lineseg intersects circle
        } else if( s instanceOf Lineseg ) {
           .... // Lineseg intersects lineseg
        } else {
          throw RuntimeException("Unrecognized shape");
        }
    }

}
于 2013-05-20T00:17:53.857 に答える