访问子类字段会导致编译器错误

时间:2011-12-05 17:54:10

标签: java oop inheritance

我有一个名为Message的超类,其字段为String msgType,另一个名为ConnectMessage的子类对其进行扩展,其中包含字段String pos_X

ConnectMessage的构造函数是:

public ConnectMessage(String msgType, String x){
    super(msgType);
    this.pos_X = x;}

在主线程中我打电话:clientMessage = Message.fromString(inputString); 其中fromString创建ConnectMessage实例,如下所示:

ConnectMessage cm = new ConnectMessage(str1, str2);
return cm;

但是当我在主线程中调用s = clientMessage.pos_X时,我收到编译器错误,说类pos_X中没有变量Message。继承如何在这里工作以及如何解决这个问题,以便语句clientMessage.pos_X表示pos_X中定义的ConnectMessage

6 个答案:

答案 0 :(得分:3)

非常明显:

您将clientMessage声明为Message类。此类有一个名为pos_x的文件。

如果要访问该字段,则必须:

  • pos_x字段拉到基类
  • clientMessage投放到ConnectMessage,即((ConnectMessage)message).pos_x

当然,我认为这个领域是公开的。

此致

答案 1 :(得分:1)

  

我已将clientMessage定义为Message clientMessage

这就是编译错误的原因。

pos_X在ConnectMessage中定义,扩展Message,因此Message不知道ConnectMessage中的字段。

解决此问题的方法:

  1. 如果你想引用它,你必须像((ConnectMessage)clientMessage).pos_X一样投射它。
  2. 将pos_X移动到Message类(这里你必须决定pos_X是否足够通用以移动到Message,如果是,请移动,如果不是,它与{{1}非常相关明天如果有一个新的派生类说ConnectMessage并且pos_X对它没有用,那就不要动了。
  3. 而不是创建DisconnectMessage执行此操作Message clientMessage,但随后您将偏离Program to Interface
  4.   

    继承如何在这里工作

    在继承子类中,子类,派生类(无论你习惯什么都称它)将从超类,父类扩展(继承)属性。

    为了使其更简单,更容易理解,

    Child取父亲姓但反向不正确,在OOP继承中的类似行上,派生类将从Parent继承反之亦然

    因此,在您的问题ConnectMessage clientMessage的上下文中,可以看到ConnectMessage中定义的属性(前提是它们不是私有的),但Message不知道Message的内部。 / p>

答案 2 :(得分:0)

pos_X只是ConnectMessage中的一个字段,而不是Message中的字段。如果您要访问的类型是Message类型,则不能保证是pos_X字段。因此,编译器会警告您访问它是不安全的。

您可以更改声明以键入ConnectMessage,然后以这种方式访问​​它,或者更改继承。

无论哪种方式,这都表明您在对象模型中做错了。 pos_X是所有消息应该具有的东西,或者pos_X是应该以更通用的方式访问所有消息的东西,或者你知道这个特定的消息实际上是一个ConnectMessage实例,并且你没有让它编译器知道。

答案 3 :(得分:0)

请尝试将clientMessage声明为ConnectMessage clientMessage;

答案 4 :(得分:0)

因为您使用clientMessage声明了Message clientMessage;,所以编译器只知道它是一个消息。因此,您只能访问Message或其父项中定义的方法/字段。由于ConnectMessage是一个子类型,您需要将clientMessage声明为ConnectMessage或使用类型转换:

if(message instanceof ClientMessage){
 ((ClientMessage)(message).pos_x;
}

答案 5 :(得分:0)

根据我对原始问题的理解,这是因为您将clientMessage标记为Message类。因此,它只能在Message类中使用变量和方法。

要解决此问题,您可以在消息

中创建此方法
public String getPos_X() { return "Sorry, this is just a Message object!"; }

然后在ConnectMessage

中覆盖它
public String getPos_X() { return pos_X; }

这样即使使用Message对象也可以调用该方法,只要它是真正的ConnectMessage对象,它就会返回正确的值。

或者如果拥有Message对象而不是ConnectMessage对象并不重要

((ConnectMessage)clientMessage).pos_X;