Доступ к полю подкласса вызывает ошибку компилятора - PullRequest
0 голосов
/ 05 декабря 2011

У меня есть суперкласс с именем Message с полем String msgType и подкласс с именем ConnectMessage, расширяющий его, который содержит поле String pos_X.

Конструктор ConnectMessageis:

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 я получаю ошибку компилятора, говоря, что в классе Message нет переменной pos_X.Как работает наследование и как я могу это исправить, чтобы выражение clientMessage.pos_X означало pos_X, определенное в классе ConnectMessage?

Ответы [ 6 ]

3 голосов
/ 05 декабря 2011

Это довольно очевидно:

вы объявили clientMessage как Message класс.Этот класс не имеет поле с именем pos_x.

. Если вы хотите получить доступ к этому полю, вам необходимо:

  • открыть pos_x поле для базового класса
  • приведение clientMessage к ConnectMessage т.е. ((ConnectMessage)message).pos_x

Конечно, я предполагаю, что поле является открытым.

Привет

1 голос
/ 05 декабря 2011

Я определил clientMessage как Сообщение clientMessage

Вот причина вашей ошибки компиляции.

И pos_X определен в ConnectMessage, что расширяет Message,следовательно, Message не знает полей в ConnectMessage.

Подход, чтобы решить эту проблему:

  1. Вам придется разыграть его как ((ConnectMessage)clientMessage).pos_X, если вы хотите обратиться кit.
  2. Переместить pos_X в Message класс (здесь вы должны решить, достаточно ли pos_X универсально, чтобы его можно было переместить на Message, если да, пожалуйста, переместите, если нет, это очень сильно связано с ConnectMessageи завтра, если есть новый производный класс, скажем, DisconnectMessage, и pos_X не будет для него полезен, тогда не двигайтесь.
  3. Вместо создания Message clientMessage сделайте это ConnectMessage clientMessage, но тогда вы отклоняетесь от Программа для интерфейса

Как здесь работает наследование

В подклассе наследования, дочернем, производном классе (назовите его так, как вам удобно)) будет расширять (наследовать) свойства от Super Class, Parent Class.

Чтобы сделать его проще и понятнее,

Ребенок получает фамилию отца , но обратное неверно, в аналогичных строках в ООП с наследованием, Производный класс будет наследовать от Parent и наоборот не соответствует действительности.

Таким образом, в контексте вашего вопроса ConnectMessage может видеть свойства, определенные в Message (при условии, что они не являются частными), но Message не знает о внутренностях ConnectMessage.

0 голосов
/ 05 декабря 2011

Из того, что я понимаю из исходного вопроса, это потому, что вы помечаете 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;
0 голосов
/ 05 декабря 2011

Поскольку вы объявили clientMessage с Message clientMessage;, компилятор точно знает, что это сообщение. Из-за этого вы можете получить доступ только к методам / полям, определенным в Message или его родителях. Поскольку ConnectMessage является подтипом, вам необходимо либо объявить clientMessage как ConnectMessage, либо использовать приведение типа:

if(message instanceof ClientMessage){
 ((ClientMessage)(message).pos_x;
}
0 голосов
/ 05 декабря 2011

Попробуйте вместо clientMessage указать ConnectMessage clientMessage;.

0 голосов
/ 05 декабря 2011

pos_X - это ТОЛЬКО поле в ConnectMessage, а не в Message.Если тип, к которому вы обращаетесь, относится к типу Message, то поле pos_X не гарантируется.Таким образом, компилятор предупреждает вас, что доступ к нему небезопасен.

Вы можете либо изменить объявление для ввода ConnectMessage, затем получить к нему доступ таким образом, либо изменить свое наследование.

ЛибоКстати, это признак того, что вы сделали что-то не так в своей объектной модели.Либо pos_X - это то, что должны иметь все Сообщения, ИЛИ pos_X - это то, к чему следует обращаться более общим способом, чем все Сообщения, ИЛИ каким-то образом вы знаете, что это конкретное Сообщение на самом деле является экземпляром ConnectMessage, и вы не позволилиКомпилятор это знает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...