Используйте объект подкласса для изменения защищенного свойства в его объекте суперкласса.

Извините за дрянной заголовок, мне не удалось придумать лучшую версию для моего вопроса о Java. Сейчас я использую версию Java: 1.6.0_18 и версию Netbeans: 6.8.

Теперь вопрос.

Что я сделал, так это создал класс только с одним защищенным свойством int, а затем я создал общедоступный метод для установки свойства int на заданное значение. Затем я создал объект этого класса и использовал указанный общедоступный метод, чтобы установить для свойства int значение 5. Теперь мне нужна ваша помощь, чтобы создать другой класс, который возьмет указанный объект и выставит его защищенное свойство int.

Я мог подумать об этом, создав подкласс, чтобы наследовать указанный класс, а затем создать метод для получения свойства int суперкласса. Мне удалось создать код для получения свойства int, но теперь я не могу понять, как использовать этот новый подкласс для ссылки на объект суперкласса.

Вот 2 класса, которые у меня есть до сих пор:

public class A
{
  protected int iNumber;

  public void setNumber ( int aNumber )
  {
    iNumber = aNumber;
  }
}
public class B extends A
{
  public int getNumber()
  {
   return super.iNumber;
  }
}

Я создал объект «A» и использовал его метод, чтобы установить его свойство равным 5, например:

A objA = new A();
objA.setNumber ( 5 );

Теперь я хочу создать объект «B» для вывода int, хранящегося в свойстве «objA». Я пытался запустить этот код:

B objB = (B) objA;
String aNumber_String = String.valueOf( objB.getNumber() );
System.out.println( aNumber_String );

but I got the error: "java.lang.ClassCastException" on the first line

 B objB = (B) objA; 

Пожалуйста, есть ли способ сделать то, что я пытаюсь сделать?

P.S. Я надеюсь, что эта идея сработает, потому что я не хочу редактировать класс A (если у меня нет выбора), предоставляя ему метод получения.

PPS Также я знаю, что это «плохая» идея — выставлять свойство вместо того, чтобы делать его приватным и использовать общедоступные методы установки/получения, но мне это нравится :).

Изменить: добавлены теги кода


person user328414    schedule 29.04.2010    source источник


Ответы (3)


Для линии

B objB = (B) objA;

объект класса A не является объектом класса B, поэтому приведение не допускается.

Классовое отношение между A и B состоит в том, что B является A (поскольку класс B расширяет A), но в этом случае нельзя сказать обратное.

Возьмем, к примеру, следующее, где существует следующее:

  • класс Animal.
  • класс Dog расширяет Animal

В приведенном выше примере делается попытка привести Animal к Dog:

Dog dogObject = (Dog)animalObject;  // Not allowed.

Это не обязательно так, поскольку не все Animal являются Dog - насколько нам известно, animalObject может быть экземпляром класса Cat, который расширяет Animal, который определенно не является Dog.

person coobird    schedule 29.04.2010
comment
Мне нравится аналогия, я понимаю, почему сейчас это не сработает, ну ладно. Спасибо :) - person user328414; 29.04.2010

Вы не можете привести объект A к B. Если вы хотите вызвать getNumber, у вас должен быть настоящий объект B:

B objB = new B();
objB.setNumber ( 5 );
System.out.println( objB.getNumber() );

Никаких отливок не требуется.

person Matthew Flaschen    schedule 29.04.2010
comment
Я этого боялся, наверное, объекты класса А теперь будут бесполезны. Спасибо :) - person user328414; 29.04.2010

Как уже говорили другие, вы не можете привести объект A к B из-за их отношений. Я бы добавил, что на самом деле это звучит так, как будто у вас есть только один класс, но у вас есть некоторые ситуации, в которых вы хотите, чтобы некоторые другие объекты не могли прочитать значение числа. Я бы сказал, что это лучше обслуживается интерфейсом. Определите интерфейс, чтобы он имел только метод setNumber(int). Определите класс, чтобы он имел методы getNumber() и setNumber(int) и реализовывал ваш интерфейс "setter". Затем везде, где у вас есть метод, который принимает объект A в качестве параметра, измените его, чтобы он принимал ваш интерфейс.

Это позволит вам иметь код, которому не разрешено получать значение объекта, но упрощает ваш код, определяя только один класс.

person Chris Shaffer    schedule 29.04.2010
comment
Мне нравится эта идея, я могу в конечном итоге использовать ее на самом деле. Спасибо :) - person user328414; 29.04.2010