Подтвердить что ты не робот

Как скрыть объект Java?

Я пытаюсь понять полиморфизм Java, и у меня есть один вопрос о downcasting объекте. Скажем, для этого примера у меня есть два подкласса Dog и Cat, которые наследуются от суперкласса Animal

Из того, что я понял, единственный способ опускать объект - это если этот объект уже имеет хороший тип, например:

Animal a = new Dog();
Dog d = (Dog) a;

Это работает правильно?

Но что, если я хочу создать обычного животного, не зная, что это будет, а затем бросить его, когда я знаю, как я могу это сделать?

Animal a = new Animal();
Dog d = (Dog) a;

Это приведет к исключению ClassCastException во время выполнения?

Единственный способ, которым я нашел это, - создать новый конструктор Dog, который создает собаку из обычного животного:

Animal a = new Animal();
Dog d = new Dog(a);

с

public Class Dog extends Animal{
   public Dog(Animal a){
      super(a);
   }
}

Итак, мой вопрос: как я должен это делать?

  • Я делаю это наилучшим образом?
  • Я не должен делать это вообще, если это нужно, значит, моя программа плохо задумана?
  • Есть ли лучший способ, который я пропустил?

Спасибо большое! nbarraille

4b9b3361

Ответ 1

Если вы хотите создать экземпляр типа, который может меняться в зависимости от нелокальных условий, используйте Аннотация Factory (as описанных в книге "Шаблоны проектирования" ).

В нем простейшая форма:

interface AnimalFactory {
    Animal createAnimal();
}

class DogFactory implements AnimalFactory {
    public Dog createAnimal() {
        return new Dog();
    }
}

Обратите внимание, что также существует разница между статическим типом ссылки и динамическим типом объекта. Даже если у вас есть ссылка Animal, если исходный объект является Dog, он все еще ведет себя как a Dog.

Ответ 2

Вы должны использовать только класс, который действительно является объектом, поэтому, если у вас есть Dog, который расширяет Animal, вы можете применить его к Animal (потому что он один), но вы не должны бросать a Animal до a Dog, потому что не все Animal являются Dog s. Класс Dog может иметь дополнительные поля, которые не реализуются классом Animal, и поэтому приведение не имеет смысла (что вы инициализируете эти значения?).

Ответ 3

Java - это строго типизированный язык, и это означает, что вы можете только передать объект к типу, из которого он распространяется (либо суперкласс, либо интерфейс).

Даже если вы "подделываете это", например. скопируйте все методы и поля классов, вы просто не можете подвергнуть объект типу, который он не расширяет.

public class Foo{

    public String phleem;

    public void bar(){

    }

}

public class Bar{

    public String phleem;

}

public interface Baz{

    public void bar();

}

Учитывая приведенный выше код, вы не можете использовать объект Foo для Bar или Baz, хотя структура класса, по-видимому, подразумевает, что вы могли бы. Наследования нет, поэтому вызывается ClassCastException.

Ответ 4

Здесь вы говорите о downcasting, поэтому в этом сценарии всегда суперкласс должен использоваться как ссылка, а дочерний объект должен указывать на это. Это usd в основном в factory patter.