0

いくつかの Java インターフェイス/ABC/クラスがあります。

public abstract class Target {
    public abstract void fire(Load load);
}

public class HttpTarget extends Target {
    @Override
    public void fire(Load load) {
        // ...
    }
}

public interface Load {
    // ...
}

public class HttpLoad implements Load {
    // ...
}

// Inside a driver
Target target = testSuite.getTarget();
Load load = testSuite.getLoad();

target.fire(load);

したがって、本質的にはTargetfire()ですLoad。私のメイン アプリは、 によって返されるの種類やによって返されるDriverの種類は気にしません。その仕事は、負荷が確実に発射されるようにすることです。TargetgetTarget()LoadgetLoad()

fire()内部のメソッド定義を次のように変更したいと思いHttpTargetます。

@Override
public void fire(HttpLoad httpLoad) {
    // ...
}

Targetしかし、私がそうすると、Java は、メソッドのオーバーライドがその親クラスによって提供される定義と一致しないと不平を言います(LoadHttpLoadは 2 つの異なるものです)。

ここでの解決策は何ですか?ジェネリック?抽象工場?最終的には、のメソッドが のみを受け入れるように強制できるようにしたいと考えていますが、それでもコードと互換性があります。HttpTargetfire()HttpLoadDriver誰かがコード例を提供できますか? 前もって感謝します!

4

2 に答える 2

4

はい、ジェネリックが必要です。

public abstract class Target<L extends Load> {
    public abstract void fire(L load);
}

public class HttpTarget extends Target<HttpLoad> {
    @Override
    public void fire(HttpLoad load) {
        ...
    }
}

public interface TestSuite<L extends Load> { // or class
    L getLoad();
    Target<L> getTarget();
}

public class HttpTestSuite implements TestSuite<HttpLoad> {
    @Override
    public HttpLoad getLoad() {
        ...
    }

    @Override
    public Target<HttpLoad> getTarget() {
        return new HttpTarget();
    }
}

fire(Load)Java が HttpTarget クラスのコンパイルを拒否する理由は、Target のメソッドをオーバーライドしないためです。実際、ターゲットは、契約により、あらゆる種類のロードを引数として受け入れることになっています。また、HttpTargetfire()メソッドは HttpLoad のインスタンスのみを受け入れるため、Liskov の原則を破っています。この問題を解決するのがジェネリックです。

于 2012-09-20T13:15:39.077 に答える
0

ジェネリックを使用する必要がありますが、それでもそれはまさにあなたが望むものではありません。

public interface Load<T extends Load> {

    public void someMethod();

}

public class HttpLoad implements Load<HttpLoad> {

    @Override
    public void someMethod() {
        System.out.println("Http Load");
                ...
    }

}

public abstract class Target<T extends Load> {

    public abstract void fire(Load<T> load);


}

public class HttpTarget extends Target<HttpLoad> {

    @Override
    public void fire(Load<HttpLoad> load) {
        load.someMethod();

    }

}

今あなたが書くなら

Target<HttpLoad> httpTarget = new HttpTarget();
Load<HttpLoad> httpLoad = new HttpLoad();
Load<OtherLoad> otherLoad = new OtherLoad();
Load otherLoad2 = new OtherLoad();

httpTarget.fire(httpLoad);
httpTarget.fire(otherLoad); // this doesn't compile
httpTarget.fire(otherLoad2) // this how ever compiles
于 2012-09-20T13:35:35.317 に答える