1

UserdataUpdater私は拡張する抽象クラスを持っていますUpdater

Updaterメソッド宣言があります

 public abstract void processRow (Cluster cluster, IAppendOnlyData row);

とにかく、このメソッド宣言をUserdataUpdaterより具体的にするために内部で変更することはありますか?

 public abstract void processRow (Cluster cluster, IUserData row);

IUserDataextends 、extendsを取得するだけIAppendOnlyDataのクラスが必要なためUserdataUpdaterIUserData

4

5 に答える 5

13

いいえ、できません。これにより、スーパークラスのコントラクトが破られます。つまり、このメソッドは2番目の引数としてIAppendOnlyDataを受け入れます。

サブクラスのインスタンスは、そのスーパークラスのインスタンスでもあることに注意してください。したがって、インスタンスが実際にサブクラスインスタンスであることを知らなくても、誰でもサブクラスインスタンスをそのスーパークラスとして参照し、基本メソッドを呼び出してIAppendOnlyDataを渡すことができます。

リスコフの置換原則についてもっと読む。

これを行う唯一の方法は、スーパークラスをジェネリックにすることです。

public class Updater<T extends IAppendOnlyData> {
    ...
    public abstract void processRow(Cluster cluster, T row);

}

public class UserdataUpdater extends Updater<IUserData> {
    @Override
    public void processRow(Cluster cluster, IUserData row) {
        ...
    }
}
于 2012-10-08T20:15:16.907 に答える
1

派生クラスのメソッド宣言は変更できません。派生クラスメソッドがまったく同じメソッドシグネチャを持っている場合にのみ、スーパークラスメソッドをオーバーライドできます。関数のオーバーロードを使用processRowして、前述の新しいパラメータータイプを使用して新しいメソッドを作成する必要があります。

于 2012-10-08T20:15:24.677 に答える
0

アップデータクラスを制御できないと仮定すると、それを行うことはできません...まったく同じシグニチャを使用してそのメソッドを実装する必要があります。ただしrow、実装内でのタイプを確認し、適切な処理を決定することができます。

public void processRow (Cluster cluster, IAppendOnlyData row)
{
    if( row instanceof IUserData )
    {
        // your processing here
    }
    else
    {
        // Otherwise do whatever is appropriate.
    }
}
于 2012-10-08T20:19:54.047 に答える
0

私の経験では、最初の宣言を使用する必要があります。次に、実装で、次のことを確認する必要があります。

row instanceof IUserData

もちろん、これはコンパイル時ではなく実行時にチェックされますが、他の方法はわかりません。もちろん、盲目的に、またはそのタイプをチェックした後(上記)にかかわらず、行をタイプIUserDataにキャストすることもできます。

于 2012-10-08T20:15:44.990 に答える
0

簡単な答え:いいえ。

このような関数を作成することはできますが、シグニチャが異なるため、コンパイラはそれを別の関数と見なします。

あなたがそれについて考えるならば、あなたがしようとしていることは本当に意味がありません。アップデータをパラメータとして受け取り、IUserDataではないものを使用してprocessRowを呼び出す関数を作成したとします。コンパイル時に、Javaには、オブジェクトがUpdater、UserdataUpdater、またはUpdaterの他のサブクラスで渡されたかどうかを知る方法がありません。それで、それは呼び出しを許可するべきかどうか?コンパイラは何をすべきですか?

実行できるのはUserdataUpdater.processRow内で、実行時に渡された型をチェックして例外をスローするか、有効でない場合は他の種類のエラー処理を行うコードを含めます。

于 2012-10-08T20:17:00.493 に答える