3

我有以下

public abstract class MyData
{
      private String sID;
      public void setsID(String sID) {
        this.sID= sID;
    }
       public String getsID() {
        return sID;
    }
} 

这个基类正在被其他 2 个类扩展

public class DataTypeOne extends MyData
{
       private String sName;
       public void setsName(String sName) {
        this.sName= sName;
        }
           public String getsName() {
            return sName;
        }
}


public class DataTypeTwo extends MyData
{
       private String sSummary;
       public void setsSummary(String sSummary) {
        this.sSummary= sSummary;
        }
           public String getsSummary() {
            return sSummary;
        }
}

我正在初始化这个类如下

MyData oDataOne = new DataTypeOne();
MyData oDataTwo = new DataTypeTwo();

原因是我有一个工厂方法,它会根据类型(一个或两个)给我一个类

使用 oDataOne 和 oDataTwo,我可以getsID()从基类访问,但不能从相应类的 getter 和 setter 访问。

我怎样才能访问这些?一世

4

4 回答 4

3

您无法访问不存在的方法。您向您的 Java 编译器承诺的oDataOne只是oDataTwo对象MyData。由于MyData该类没有特定于实现的方法,因此您不能要求 Java 调用这些方法(因为它认为它们不存在)。

如果要访问这些方法,则需要将对象强制转换为实际具有正确方法的类,或者可以将抽象方法存根添加到基类,这将告诉 Java 这些方法确实存在。

类型转换在短期内写起来更简单,但不太清楚,你可能会遇到更多麻烦:

((DataTypeOne) oDataOne).getsName();
((DataTypeTwo) oDataOne).getsSummary(); // Throws ClassCastException!

添加抽象存根更健壮,但如果不是所有具体子类都应该实现所有抽象方法,则可能没有意义:

public abstract class MyData {
    public abstract void setsName(String name);
    public abstract String getsName();
    public abstract void setsSummary(String summary);
    public abstract String getsSummary();
}
public class DataTypeOne extends MyData {
    public String getsName() {
        // implement
    }
    public void setsName(String name) {
        // implement
    }

    // Still have to implement these!!!
    public String getsSummary() {
        // raise an exception or something if appropriate
    }
    public void setsSummary(String summary) {
        // raise an exception or something if appropriate
    }
}
// Same for DataTypeTwo
于 2013-04-04T13:39:21.213 回答
2

由于您将变量声明为 MyData,因此您只能访问 MyData 的方法。您可以通过将其转换为 DataTypeOne 或 DataTypeTwo 来访问子类方法:

 ((DataTypeOne)oDataOne).getsName()

但是你需要确保它是 DataTypeOne 类型,否则你会得到一个ClassCastException

于 2013-04-04T13:40:24.760 回答
1
MyData oDataOne = new DataTypeOne();

这说,你的oDataOne对象是类型MyData。即使它被创建为DataTypeOne,java 也只能确定它绝对是一个MyData实例。

如果您确定该MyData实例实际上也是一个DataTypeOne实例,则可以强制转换然后访问DataTypeOne方法+MyData方法。

确保对象属于特定类型测试:

if(oDataOne instanceOf DataTypeOne){
    ((DataTypeOne) oDataOne).getsName();  // this will return the Name if oDataOne is really of the type DataTypeOne
}
于 2013-04-04T13:42:44.270 回答
0

类型的对象MyData不知道是否有任何其他类扩展它,因此无法访问这些类的成员。

您必须将对象转换为特定类型才能访问特定成员。

如果你发现自己处于这种情况,你可以很确定你的设计是有缺陷的。如果您需要为每种类型的MyData扩展执行特定的操作,请添加一个方法,例如specialAction()到接口并隐藏其中的细节。这消除了找出您正在处理的子类的全部需要。

于 2013-04-04T13:40:00.237 回答