tiempo sirve showmessagedialog showinputdialog segundos que programacion para mostrar metodo mensaje error ejemplos ejecutar cierto cada java generics polymorphism overloading method-overloading

sirve - mostrar mensaje en java netbeans



Método que acepta dos tipos diferentes como parámetro (8)

¿Qué tal algo tan simple como esto?

utterlyDestroy(Object parameter) { if(parameter instanceOf Dreams){ Dream dream = (Dreams)parameter; dream.crush(); //Here you can use a Dream } else if(parameter instanceOf Garlic){ Garlic garlic = (Garlic)parameter; //Here you can use a Garlic garlic.crush(); } }

Si el utterlyDestroy es demasiado complejo y grande y solo quieres llamar al crush entonces esto hace lo que quieres

Estoy escribiendo un método que debería aceptar como parámetro un objeto de uno de dos tipos que no comparte un tipo principal que no sea Objeto. Por ejemplo, los tipos son sueños y ajo. Puedes hacer ambos dreams.crush() y garlic.crush() . Quiero tener un método completamente utterlyDestroy(parameter) , que acepte como parámetro tanto los Sueños como el Ajo.

utterlyDestroy(parameter) { parameter.crush() }

Tanto Ajo como los sueños son parte de alguna biblioteca, por lo que hacer que implementen una interfaz que se puede configurar con ICrushable (de modo que pueda escribir completamente utterlyDestroy(ICrushable parameter) ) no es una opción.

Mi cuerpo de método es bastante largo, por lo que sobrecargarlo significaría duplicar código. Feo. Estoy seguro de que podría usar la reflexión y hacer piratería de clase. Feo.

Intenté usar genéricos pero aparentemente no puedo escribir algo como

utterlyDestroy(<T instanceof Dreams || T instanceof Garlic> parameter)

¿Es posible encasillar Garlic to Dreams?

utterlyDestroy(Object parameter) { ((Dreams)parameter).crush() }

Aunque esto todavía sería feo. ¿Cuáles son mis otras opciones y cuál es el método preferido para enfrentar la situación?


Como estoy usando:

void fooFunction(Object o){ Type1 foo=null; if(o instanceof Type1) foo=(Type1)o; if(o instanceof Type2) foo=((Type2)o).toType1(); // code }

Pero eso solo funciona si Type2 puede convertirse a Type1


Crear una interfaz aplastable parece ser la forma más limpia de hacerlo. ¿Subtitular el ajo o los sueños es una opción, y agregar su interfaz al subtipo?

De lo contrario, puede poner el código común en un método privado y hacer que las dos versiones de completamente destruyan lo que tienen que hacer con los objetos individuales antes de llamar al código común. Si el cuerpo del método es largo, es probable que tenga que dividirlo en métodos privados de todos modos. Sin embargo, supongo que ya pensaste en esto, ya que es una solución aún más obvia que agregar una interfaz.

Puedes traer el parámetro como un Objeto y luego lanzarlo. ¿Es esto lo que quieres decir con reflexión? es decir,

public void utterlyCrush(Object crushable) { if (crushable instanceOf Dream) { ... } if (curshable instanceOf Garlic) { ... }

Pero lanzar de Ajo a Sueño no es una opción dado que uno no es un subtipo del otro.


Podrías usar una interfaz y adapt tus tipos a ella.

Interfaz:

public interface Crushable { public void crush(); }

Ejemplo de invocación:

public class Crusher { public static void crush(Crushable crushable) { crushable.crush(); } }

Ejemplo de método de fábrica del adaptador:

public final class Dreams { public static Crushable asCrushable(final Dream dream) { class DreamCrusher implements Crushable { @Override public void crush() { dream.crush(); } } return new DreamCrusher(); } private Dreams() {} }

El código del consumidor se ve así:

Dream dream = new Dream(); Crushable crushable = Dreams.asCrushable(dream); Crusher.crush(crushable);

Si tienes muchos tipos para adaptarte, podrías considerar la reflexión. Aquí hay una fábrica de adaptadores (no optimizada) que usa el tipo Proxy :

public final class Crushables { private static final Class<?>[] INTERFACES = { Crushable.class }; public static Crushable adapt(final Object crushable) { class Handler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return crushable.getClass() .getMethod(method.getName(), method.getParameterTypes()) .invoke(crushable, args); } } ClassLoader loader = Thread.currentThread() .getContextClassLoader(); return (Crushable) Proxy.newProxyInstance(loader, INTERFACES, new Handler()); } private Crushables() {} }

Para el consumidor de API, esto no es tan feo:

Dream dream = new Dream(); Crushable crushable = Crushables.adapt(dream); Crusher.crush(crushable);

Sin embargo, como es habitual con la reflexión, se sacrifica la comprobación de tipos en tiempo de compilación.


Puede implementar un Haskell-esque Either-class en Java; algo como esto:

class Either<L,R> { private Object value; public static enum Side {LEFT, RIGHT} public Either(L left) {value = left;} public Either(R right) {value = right;} public Side getSide() {return value instanceof L ? Side.LEFT : Side.RIGHT;} // Both return null if the correct side isn''t contained. public L getLeft() {return value instanceof L ? (L) value : null;} public R getRight() {return value instanceof R ? (R) value : null;} }

Luego dejas que el método tome algo de tipo Either<Dreams, Garlic> .


Qué tal esto:

interface ICrushable { void crush(); } utterlyDestroy(ICrushable parameter) { // Very long crushing process goes here parameter.crush() } utterlyDestroy(Dreams parameter) { utterlyDestroy(new ICrushable() { crush() {parameter.crush();}); } utterlyDestroy(Garlic parameter) { utterlyDestroy(new ICrushable() { crush() {parameter.crush();}); }

El nuevo desarrollo debe implementar la interfaz ICrushable, pero para las Clases existentes, el parámetro se envuelve en un ICrushable y se pasa al completo Destrucción (ICrushable) que hace todo el trabajo.


Si va a tratarlos de la misma manera en muchos lugares de su proyecto, le sugiero que los envuelva en una clase, algo así como un adaptador.


Simplemente use el método de sobrecarga.

public void utterlyDestroy(Dreams parameter) { parameter.crush(); } public void utterlyDestroy(Garlic parameter) { parameter.crush(); }

Si desea admitir más de estos dos tipos de la misma manera, puede definir una interfaz común para todos ellos y usar genéricos.