2

Javaで潜在的に異なる型になる可能性のある変数を持つことが可能かどうか疑問に思っていましたか? 具体的には、異なるクラスの 2 つの異なるオブジェクトがあり、どちらもテーブルです。だから、私たちが持っているとしましょう:

TableTypeA t1;
TableTypeB t2;

両方のクラスに getSelectedRow() というメソッドがあるとします。次のことができるように 3 番目の変数を作成することは可能ですか?

SomeType t3;
t3 = t1; 
t3.getSelectedRow();

t3 = t2;
t3.getSelectedRow();

TableTypeA と TableTypeB は同じクラスを拡張しません。最も近い共通のスーパークラスには getSelectedRow() メソッドがありません。それらがどのように機能するかを見て、おそらくそのうちの1つが他のクラスを拡張するか、それらのクラスをマージする必要がありますが、そのような構造変更はオプションではないとしましょう。私が提案していることは可能ですか?

ありがとう。

編集: これらのインターフェイスを追加すると思います。すべての迅速な対応に感謝します!

4

9 に答える 9

3

クラスが を持つインターフェイスを実装している場合はgetSelectedRow()、確かに。

このような変更は、クラス階層の再編成がそうであるという意味で、構造的/組織的ではありません。

于 2012-07-17T23:00:02.550 に答える
2

(基本クラスから派生するのではなく)と呼ばれるインターフェイスTableTypeATableTypeB実装している場合は可能です。例えば:SomeType

interface SomeType {
    Row getSelectedRow();
}

class TableTypeA implements SomeType {
    Row getSelectedRow() {
        // ...
    }
}

class TableTypeB implements SomeType {
    Row getSelectedRow() {
        // ...
    }
}

そうでない場合は、リフレクションを経由する必要があります。

于 2012-07-17T23:02:10.413 に答える
1

...しかし、そのような構造変更はオプションではないとしましょう。私が提案していることは可能ですか?

関連する型を変更しないと、それを行うことはできません。あなたが望むことができる最善instanceofの方法は、キャストを使用していくつかの醜いコードを記述し、それをメソッド内に隠すことです。リフレクションは代替手段ですが、それはより醜く、より高価です(IMO)。

于 2012-07-17T23:04:27.560 に答える
1

インターフェースで可能です:

public interface Table {
    Row getSelectedRow();
}

public class TableTypeA implements Table {
    Row getSelectedRow() {    // Must be defined

    }
}

public class TableTypeB implements Table {
    Row getSelectedRow() {    // Must be defined

    }
}

クラスのアーキテクチャを変更することなく、instanceof演算子と型キャストを使用できます。

于 2012-07-17T23:01:44.990 に答える
0

インターフェイスを共有している場合のみ。これは JavaScript とは異なります。

于 2012-07-17T23:03:07.883 に答える
0

いいえ、Java はダック タイピングをサポートしていません。

于 2012-07-17T23:03:34.513 に答える
0

共通のインターフェースまたはスーパークラスがなければ、いいえ、単純な方法ではありません。コンパイラは代入について不平を言い、明示的なキャストを要求します。明示的なキャストはClassCastException.

別の方法は、リフレクションを使用することです。

于 2012-07-17T23:02:04.517 に答える
0

元のクラスを制御しない場合は、アダプターが役立ちます http://en.wikipedia.org/wiki/Adapter_pattern

public interface TableAdapter {
    Row getSelectedRow();
}

public class TableTypeAAdapter implements TableAdapter {
    private TableTypeA tableTypeA;
    public TableTypeAAdapter(TableTypeA tableTypeA) {
        this.tableTypeA = tableTypeA;
    }

    public Row getSelectedRow() {
        tableTypeA.getSelectedRow();
    }
}

そして、TableTypeB の同様のクラス

それで:

TableAdapter table = new TableTypeAAdapter(tableTypeA);
table.getSelectedRow();

table = new TableTypeBAdapter(tableTypeB);
table.getSelectedRow();
于 2012-07-18T01:17:28.490 に答える
0

この動作が必要であり、スーパー クラス/実装インターフェイスを変更できない場合は、ラッパー クラスを作成するしかありません。

interface Table{ Row getSelectedRow(); }

class WrapperA extends TableTypeA implements Table{
  // copy all constructors and forward to super()
}

class WrapperB extends TableTypeB implements Table{
  // same
}
于 2012-07-17T23:48:35.697 に答える