33

2つのサブクラスとVehicleが実装された抽象クラスがあります。RedVehicleYellowVehicle

別のクラスには、List<Vehicle>両方のサブクラスのインスタンスが含まれています。メソッドにクラス型を渡し、その型を使用して、で何かを実行するオブジェクトのセットを決定できるようにしたいですList

は一般的であるためClass、何かを使用してパラメーター化する必要がありますが、パラメーターを親クラスとして配置すると、またはのサブクラスではなく、Vehicleのタイプが必要になるVehicleため、呼び出し元のコードが機能しなくなります。exampleMethodRedVehicleYellowVehicle

これを行うためのクリーンな方法があるはずだと思うので、機能を実装する正しい方法は何でしょうか?

nb必ずしもClassタイプを渡す必要はありません。もっと良い提案があれば、喜んで試してみます。

発信コード:

service.exampleMethod(RedVehicle.class);
service.exampleMethod(YellowVehicle.class);

フィールド/方法:

//List of vehicles
//Vehicle has 2 subclasses, RedVehicle and YellowVehicle
private List<Vehicle> vehicles;

//Having <Vehicle> as the Class parameter stops the calling code working
public void exampleMethod(Class<Vehicle> type) 
{
    for(Vehicle v : vehicles)
    {
        if(v.getClass().equals(type))
        {
            //do something
        }
    }
}
4

3 に答える 3

67

代わりにこれを行ってください:

public <T extends Vehicle> void exampleMethod(Class<T> type) 
于 2012-10-24T19:45:41.547 に答える
4

ビジターパターンを使ってみませんか?

そうすればあなたは

  • タイプトークンは必要ありません
  • 動的ディスパッチに大文字と小文字の区別を処理させます(の代わりにif(v.getClass().equals(type))
  • より柔軟です(OCPに準拠)

詳細に:

抽象クラスVehicleはメソッドaccept(Visitor v)を取得し、サブクラスはで適切なメソッドを呼び出すことによってそれを実装しvます。

public interface Visitor {
  visitRedVehicle(RedVehicle red);
  visitYellowVehicle(YellowVehicle yellow);
}

訪問者の使用:

public class Example {

  public void useYellowOnly() {
    exampleMethod(new Visitor() {
        visitRedVehicle(RedVehicle red) {};
        visitYellowVehicle(YellowVehicle yellow) {
             //...action
        });
  }
  public void exampleMethod(Visitor visitor){
      for(Vehicle v : vehicles) {
          v.accept(visitor);
      }  
  }
}
于 2012-10-24T21:43:59.133 に答える
0

受け入れられた答えはうまくいき、私が行きたいところに私を連れて行きました。これを追加して、必要になる可能性のある人にわかりやすくすることを考えました。

この場合、RevisedExposureはExposureのサブクラスです。これらのいずれかのリストを使用してGetMetadata()を呼び出す必要があります。これにより、同じ結果セットが得られます。

private async Task<List<Metadata>> GetMetadata<T>(List<T> exposures) where T : Exposure

これで、このようなリストのバージョンが異なる2つの場所からこのメソッドを呼び出すことができます。

var metadata = await GetExposureMetadata(revisions);

また

var metadata = await GetExposureMetadata(exposures);

よく働く!

于 2021-03-03T17:33:01.020 に答える