2

我想知道在 Java 中是否有可能有一个可能是不同类型的变量?具体来说,我有两个不同类的不同对象,它们都是表。所以假设我们有:

TableTypeA t1;
TableTypeB t2;

假设这两个类都有一个名为 getSelectedRow() 的方法,我是否可以创建第三个变量以便我可以执行以下操作:

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

t3 = t2;
t3.getSelectedRow();

TableTypeA 和 TableTypeB 没有扩展同一个类,它们最接近的公共超类没有 getSelectedRow() 方法。看看它们的功能有多相似,其中一个可能应该扩展另一个,或者它们的类应该已经合并在一起,但是假设这样的结构变化不是一种选择,我建议可以做吗?

谢谢。

编辑:我想我会为这些添加一个界面,非常感谢您的所有快速回复!

4

9 回答 9

3

如果这些类实现了一个具有 的接口,那是getSelectedRow()肯定的。

从重新组织类层次结构的意义上说,这种变化不是结构性/组织性的。

于 2012-07-17T23:00:02.550 回答
2

有可能,如果TableTypeA并且TableTypeB两者都实现了一个名为(而不是从基类派生)的接口。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

如果您需要这种行为并且您不能更改超类/实现接口,那么您所能做的就是创建包装类。

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 回答
0

仅当它们共享一个接口时。这不像 JavaScript。

于 2012-07-17T23:03:07.883 回答
0

不,Java 不支持鸭子类型

于 2012-07-17T23:03:34.513 回答
0

If you don't control the original classes, Adapters can come in handy 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();
    }
}

And a similar class for TableTypeB

Then:

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

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

没有通用接口或超类,不,不是直接的方式。编译器将抱怨分配并请求显式转换。显式强制转换会导致ClassCastException.

另一种方法是使用反射。

于 2012-07-17T23:02:04.517 回答