suppresswarnings sirven sirve que para las ejemplo crear anotaciones annotation java oop inheritance downcasting

java - ejemplo - para que sirven las anotaciones



¿Cómo abatir un objeto Java? (4)

Aquí se está hablando de reducción de nivel, por lo que en este escenario, siempre se debe utilizar la superclase como referencia y el objeto secundario debe señalarse con eso. Esto usd básicamente en patrón de fábrica.

Estoy tratando de entender el polimorfismo de Java, y tengo una pregunta sobre cómo derribar un objeto. Digamos que para este ejemplo tengo dos subclases Perro y Gato que heredan de una superclase Animal

Por lo que entendí, la única manera de derribar un objeto es si este Objeto ya es del tipo correcto, como este:

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

Esto funciona bien?

Pero, ¿qué pasa si quiero crear un animal normal sin saber lo que sería y luego lanzarlo cuando lo sé, cómo puedo hacerlo?

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

Esto lanzará una ClassCastException en tiempo de ejecución ¿verdad?

La única forma que encontré para hacerlo es crear un nuevo constructor de perros que cree un perro a partir de un animal normal:

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

con

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

Entonces mi pregunta es, ¿cómo se supone que debo hacer esto?

  • ¿Lo estoy haciendo de la mejor manera?
  • ¿Se supone que no debo hacer esto en absoluto, si tengo que hacerlo significa que mi programa no está bien concebido?
  • ¿Hay alguna forma mejor de que me haya perdido?

¡Muchas gracias! Nbarraille


Java es un lenguaje fuertemente tipado, y eso significa que solo puede convertir un objeto a un tipo al que se extiende (ya sea una superclase o una interfaz).

Incluso si lo "falsifica", por ejemplo, si copia todos los métodos y campos de una clase, simplemente no puede convertir un objeto en un tipo que no se extienda.

public class Foo{ public String phleem; public void bar(){ } } public class Bar{ public String phleem; } public interface Baz{ public void bar(); }

Dado el código anterior, no puedes lanzar un objeto Foo a una Bar o a un Baz , aunque la estructura de clase parece implicar que puedes hacerlo. No hay herencia involucrada, por lo que se lanza una ClassCastException .


Si desea crear una instancia de un tipo que puede variar según las condiciones no locales, use un Abstract Factory (como se describe en el libro Patrones de diseño).

En su forma más simple:

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

Tenga en cuenta que también hay una diferencia entre el tipo estático de una referencia y el tipo dinámico del objeto. Aunque tengas una referencia de Animal , si el objeto original es un Dog , todavía se comporta como un Dog .


Solo debes lanzar a una clase que el objeto realmente es, así que si tienes un Dog que extiende el Animal , puedes lanzarlo a un Animal (porque es uno) pero no debes lanzar un Animal a un Dog porque no todos los Animal s son Dog s. La clase Dog puede tener campos adicionales que no están implementados por la clase Animal , por lo que el elenco no tiene sentido (¿a qué se inicializan esos valores?).