3

私は今朝、同様の質問をしましたが、答えられたと思っていましたが、提案されたソリューションを実際に実装しましたが、必要なことを実行できませんでした。だからここに私の完全な問題があります:

私は次のクラスを持っています:

// Objects to process.
public class Apple {
    private Color color;
    private int numberOfSeeds;
    // ...
}

public class Chair {
    private Material madeOutOfMaterial;
    private double price;
    // ...
}

public class CellPhone {
    private Manufacturer make;
    private String model;
    private boolean isSmartPhone;
    // ...
}

// Contains the object that will be processed (an Apple, Chair, CellPhone instance, etc.)
// as well as metadata info about the processing itself (timestamp, a UUID for tracking
// purposes, etc.).
public class ProcessingMetadata<PROCESSABLE_OBJECT> {
    private PROCESSABLE_OBJECT result;
    private Date processedOnDate;
    private String uuid;
    // ...
}

// Abstract base class for processing PROCESSABLE_OBJECTs.
public abstract class ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> {
    private String name;

    public abstract ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data);
}

// One concrete processor.
public class SimpleObjectProcessor extends ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> {
    private Fizz fizz;

    @Override
    public ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data) {
        // Processes data one way, and returns a PROCESSABLE_OBJECT.
    }
}

// Another concrete processor.
public class ComplexObjectProcessor extends ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> {
    private Buzz buzz;

    @Override
    public ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data) {
        // Processes data differently, and returns a PROCESSABLE_OBJECT.
    }
}

これらのクラスをすべて使用した最終的なコードは次のようになります。

ObjectProcessor<ProcessingMetadata<Apple>> appleProcessor =
        new ComplexObjectProcessor<ProcessingMetadata<Apple>>();
Data data = getData();

ProcessingMetadata<PROCESSABLE_OBJECT> meta = appleProcessor.process(data);

Apple apple = meta.getResult();
Date processedOn = meta.getProcessedOnDate();
String uuid = meta.getUUID();

これが開発者に公開したい「API」です。いくつかDataを取得し、型指定されたプロセッサを選択し、データを処理して、必要なすべてのメタデータを取得します。

問題は、私ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>>が合法ではないということです。ProcessingMetadataクラス定義の部分で次のコンパイラ エラーが発生します。

トークンの構文エラー、構造体の配置ミス

私は午前中ずっとこのクラス (およびその具体的なサブクラス) をいじりましたが、必要な API を提供するためにジェネリックを正しくセットアップできないようです。私は、 が実際に 、 、 、 などのインターフェイスであることを要求することにオープンです。それをPROCESSABLE_OBJECT実装します。しかし、クライアントが何を処理したいかはわかりません。そのため、可能であれば、POJO にインターフェースを実装させることを強制したくありません。ProcessableAppleChairProcessabl

それで、私の望むAPIは可能ですか?もしそうなら、どのように?そうでない場合、その理由と、それに最も近いものは何ですか? 前もって感謝します!

4

3 に答える 3

3

型パラメーター リスト内の各項目は、型パラメーターである必要があります。ObjectProcessor のクラス宣言でProcessingMetadata<PROCESSABLE_OBJECT>は、ジェネリック型パラメーターではありません。

PROCESSABLE_OBJECT をパラメーター化された型として指定し、ProcessingMetaData を拡張する型を別のパラメーター化された型として指定できます。

public abstract class ObjectProcessor< 
   PROCESSING_METADATA extends ProcessingMetadata<PROCESSABLE_OBJECT>, 
   PROCESSABLE_OBJECT > 
{ ... }

編集:

サブクラスもパラメーター化された型です。クラス自体でこれらの型パラメーターを宣言する必要があります。次に、それらを使用してスーパークラスをパラメーター化できます。

public class SimpleObjectProcessor<
   PROCESSING_METADATA extends ProcessingMetadata<PROCESSABLE_OBJECT>, 
   PROCESSABLE_OBJECT > 
extends ObjectProcessor< PROCESSING_METADATA,PROCESSABLE_OBJECT > 
{ ... }
于 2013-06-27T16:31:44.327 に答える
1

あなたのAPIでは、開発者はこの行を使用すると思います

ProcessingMetadata<PROCESSABLE_OBJECT> meta = appleProcessor.process(data);

このように

ProcessingMetadata<Apple> meta = appleProcessor.process(data);
于 2013-06-27T16:54:03.430 に答える
0

クラス宣言自体は型パラメーター宣言のみを取りますが、ProcessingMetadataそこに入れようとします。

public abstract class ObjectProcessor<PROCESSABLE_OBJECT> {
    private String name;

    public abstract ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data);
}

public class SimpleObjectProcessor<PROCESSABLE_OBJECT>
        extends ObjectProcessor<PROCESSABLE_OBJECT> {
    private Fizz fizz;

    @Override
    public ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data) {
        // Processes data one way, and returns a PROCESSABLE_OBJECT.
    }
}

ObjectProcessor<Apple> appleProcessor = new ComplexObjectProcessor<Apple>();
// Note: there is no PROCESSABLE_OBJECT here. Use the concrete type:
ProcessingMetadata<Apple> meta = appleProcessor.process(data);
于 2013-06-27T16:38:45.940 に答える