setborder - Java 8 agrega extensión/método predeterminado a la clase
swing java (4)
Es posible tener métodos de extensión con algunos trucos.
Puedes darle una oportunidad a Lombok o XTend. Aunque los métodos de extensión no vienen con la implementación de Java fuera de la caja, tanto Lombok como XTend ofrecen una solución completamente funcional.
Lombok es un marco de procesamiento de código autónomo simple, que hace que la mayoría de los problemas específicos criticados de Java sean menos dolorosos, incluidos los métodos de extensión: https://projectlombok.org/features/experimental/ExtensionMethod.html
Xtend http://www.eclipse.org/xtend/ avanza unos años luz e implementa un lenguaje que es una combinación de las mejores partes de lenguajes modernos como Scala sobre Java y el sistema de tipo Java. Esto permite implementar algunas clases en Xtend y otras en Java dentro del mismo proyecto. El código Xtend cumple con el código de Java válido, por lo que no hay magia JVM bajo el capó. Por otro lado, es demasiado si solo faltan los métodos de extensión.
JPropel https://github.com/nicholas22/jpropel-light implementa métodos de extensión de estilo LINQ en Java usando Lombok. Puede valer la pena un vistazo :)
Estoy buscando un java equivalente a la función de métodos de extensión C #. Ahora he estado leyendo sobre los métodos predeterminados de Java 8, pero por lo que puedo ver, solo puedo agregarlos a las interfaces ...
... ¿hay alguna característica de lenguaje que me permita escribir un método de extensión para una clase final que no implementa una interfaz? (Prefiero no tener que envolverlo ...)
Java no tiene métodos de extensión. Los métodos predeterminados no son métodos de extensión. Veamos cada característica.
Métodos por defecto de Java
Problemas resueltos:
- Muchos objetos pueden implementar la misma interfaz y todos ellos pueden usar la misma implementación para un método. Una clase base podría resolver este problema, pero solo si los implementadores de la interfaz aún no tienen una clase base, ya que java no admite la herencia múltiple.
- Una API desea agregar un método a una interfaz sin interrumpir a los consumidores de la API. Agregar un método con una implementación predeterminada resuelve esto.
Los métodos predeterminados de Java son una característica para agregar una implementación predeterminada a una interfaz. Por lo tanto, los objetos que extienden una interfaz no tienen que implementar el método, solo podrían usar el método predeterminado.
interface IA { default public int AddOne(int i) { return i + 1; } }
Cualquier objeto que implemente IA no tiene que implementar AddOne porque hay un método predeterminado que se usará.
public class MyClass implements IA { /* No AddOne implementation needed */ }
C # carece de esta función y se mejoraría enormemente al agregar esta función. (Actualización: La característica viene en C # 8)
Método de extensión de C #
Problemas resueltos:
- Posibilidad de añadir métodos a clases selladas.
- Posibilidad de agregar métodos a clases de bibliotecas de terceros sin forzar la herencia.
- Posibilidad de agregar métodos para modelar clases en entornos donde los métodos en clases modelo no están permitidos por razones de convención.
- La capacidad de inteligencia para presentarle estos métodos.
Ejemplo: la cadena de tipo es una clase sellada en C #. No se puede heredar de una cadena como está sellada. Pero puedes agregar métodos a los que puedas llamar desde una cadena.
var a = "mystring";
a.MyExtensionMethed()
Java carece de esta función y se mejoraría enormemente al agregar esta función.
Conclusión
No hay nada similar en los métodos predeterminados de Java y en las características del método de extensión de C #. Son completamente diferentes y resuelven problemas completamente diferentes.
Los métodos de extensión C # son simplemente azúcar sintáctica para métodos estáticos que toman el tipo extendido como primer argumento. Los métodos predeterminados de Java son algo completamente diferente. Para imitar los métodos de extensión C #, simplemente escriba los métodos estáticos habituales. Sin embargo, no tendrás el azúcar sintáctico; Java no tiene esta característica.
Los métodos predeterminados de Java son métodos virtuales reales. Por ejemplo, se pueden anular. Considere una clase X
heredada de una interfaz I
que declara un método foo()
predeterminado. Si X
o cualquiera de sus súper clases no declaran ningún método foo()
, entonces X
obtendrá la implementación foo()
de I
Ahora, una subclase Y
de X
puede anular X.foo()
como un método habitual. Por lo tanto, los métodos predeterminados no son solo azúcar sintáctica. Son extensiones reales del mecanismo de anulación y herencia del método que no pueden ser imitadas por otras características del lenguaje.
Los métodos predeterminados incluso requieren un soporte especial de VM, por lo que ni siquiera son una característica exclusiva del compilador: durante la carga de clases, se debe verificar la jerarquía de una clase para determinar qué métodos predeterminados heredará. Por lo tanto, esta decisión se toma en tiempo de ejecución, no en tiempo de compilación. Lo bueno de esto es que no tiene que volver a compilar una clase cuando la interfaz que hereda obtiene un nuevo método predeterminado: la VM, en el momento de carga de la clase, le asignará ese nuevo método.
Los métodos de extensión de C # son estáticos y de sitio de uso , mientras que los métodos predeterminados de Java son virtuales y de sitio de declaración .
Lo que creo que estás esperando es la capacidad de "parchear" un método en una clase que no controlas, pero Java no te da eso (por diseño, fue considerado y rechazado).
Otro beneficio de los métodos predeterminados sobre el enfoque de C # es que son detectables de manera reflexiva y, de hecho, desde el exterior, no se parecen en nada a los métodos de interfaz "normales".
Una ventaja de los métodos de extensión de C # sobre los métodos predeterminados de Java es que con los genéricos reificados de C #, los métodos de extensión se inyectan en tipos , no en clases , por lo que puede inyectar un método sum()
en List<int>
.
Por encima de todo, la principal diferencia filosófica entre los métodos predeterminados de Java y los métodos de extensión de C # es que C # le permite inyectar métodos en tipos que no controla (lo que seguramente es conveniente para los desarrolladores), mientras que los métodos de extensión de Java son una parte de primera clase de la API. en el que aparecen (se declaran en la interfaz, se pueden descubrir de manera reflexiva, etc.) Esto refleja varios principios de diseño; los desarrolladores de bibliotecas deberían poder mantener el control de sus API, y el uso de la biblioteca debería ser transparente: el método de llamada x()
en el tipo Y
debería significar lo mismo en todas partes.