Estoy leyendo Programming Scala. Al comienzo del capítulo 4, el autor comenta que Java admite métodos estáticos, que son "conceptos OO no tan puros". ¿Por qué esto es tan?¿Por qué los métodos estáticos no se consideran una buena práctica de OO?
Respuesta
Una razón por la que los métodos estáticos no son muy OO que no se hayan mencionado hasta ahora es que las interfaces y las clases abstractas solo definen métodos no estáticos. Los métodos estáticos no encajan muy bien en la herencia.
Tenga en cuenta también que los métodos estáticos no tienen acceso a "super
", lo que significa que los métodos estáticos no pueden anularse en ningún sentido real. En realidad, no pueden ser anulados en absoluto, solo ocultos. Pruebe esto:
public class Test {
public static int returnValue() {
return 0;
}
public static void main(String[] arg) {
System.out.println(Test.returnValue());
System.out.println(Test2.returnValue());
Test x = new Test2();
System.out.println(x.returnValue());
}
}
public class Test2 extends Test {
public static int returnValue() {
return 1;
}
}
Cuando ejecuta esto, no obtendrá lo que espera. Test.returnValue()
da lo que esperas. Test2.returnValue()
oculta el método del mismo nombre en la superclase (no lo anula), y da lo que cabría esperar.
Uno ingenuamente podría esperar "no estáticamente" llamar a un método estático para usar polimorfismo. No es así Cualquiera sea la clase en que se declare la variable, es la que se usa para buscar el método. Esta es una mala forma porque alguien podría esperar que el código haga algo diferente de lo que realmente hace.
Esto no significa, "¡No use métodos estáticos!"Significa que debe reservar el uso de métodos estáticos para aquellas instancias en las que realmente desea que el objeto Class sea propietario del método, y no solo como una forma perezosa de crear un singleton.
Esta respuesta probablemente tiende a tener más sentido de lo que he visto hasta ahora. Romper uno de los conceptos de trinidad ciertamente va contra corriente. – Mike
No es que esté disputando esto, pero el ejemplo que muestra solo se aplica a Java, ¿verdad? IIRC, Java es el único lenguaje OO (que he encontrado) que permite llamar funciones estáticas a través de una instancia de la clase. –
@Jeff: VB.NET también permite este comportamiento sin sentido. –
Los métodos estáticos no son conceptos de OO tan puros porque se pueden invocar sin que realmente se asocie un objeto. Usas la clase en sí. Los invocará así Classname.method(...);
¿Qué ocurre si uso algo como Ruby, que admite clases como objetos e invocación estática? De hecho, un objeto estaría asociado con la llamada estática. – Mike
Bueno, no estoy seguro de qué tan asociado a Java fue el autor cuando dijo lo que hizo, pero la cosa es que incluso en Java hay objetos que se crean y administran para representar las clases también, así que esto es un poco discutible , hasta cierto punto. Sin embargo, la simple idea de que tiene un método principal estático y los métodos estáticos que puede invocar sin tener ningún objeto lo hace un poco contrario al paradigma de OOP. –
El concepto de OO se refiere a controlar/acceder a los datos de un objeto, pero no es necesario llamar a los métodos estáticos con un objeto y pertenecen a la clase en lugar de a un objeto.
--Cheers
No se debe confundir "conceptos OO no tan puros" con "mala práctica". Ser "OO puro" no es una panacea que deba intentar lograr. El hecho de que los métodos estáticos no tomen una variable de instancia como parámetro no significa que no sean útiles. Algunas cosas simplemente no se prestan a los objetos, y no deberían forzarse en ese molde solo por el bien de la "pureza".
Algunas personas piensan que las cosas deben ser "puras", y por lo tanto, cualquier cosa "impura" es una mala práctica. En realidad, una mala práctica es hacer cosas que son confusas, difíciles de mantener, difíciles de usar, etc. La creación de métodos estáticos que toman una instancia es una mala práctica porque cualquier método que tome una instancia probablemente sea un método de instancia. Por otro lado, cosas como la utilidad y las funciones de fábrica generalmente no toman una instancia, por lo que debe ser estático.
Si se pregunta por qué no son "OO puros", es porque no son métodos de instancia. Un lenguaje OO "puro" tendría todo como un objeto y todas las funciones serían métodos de instancia. Por supuesto, eso no es terriblemente útil todo el tiempo. Por ejemplo, considere el método Math.atan2
. Toma dos números y no requiere ningún estado. ¿Qué objeto podría incluso convertirlo en un método de? En un lenguaje OO "puro", Math
podría ser un objeto (un singleton, probablemente), y atan2
sería un método de instancia, pero dado que la función no usa ningún estado en el objeto Math
, tampoco es un concepto "OO puro".
Tenga en cuenta que nunca dije que era una mala práctica, por lo que mi pregunta no fue realmente respondida. ;) – Mike
Es cierto. Por otro lado, he visto demasiados códigos en los que todo es un singleton y todo es estático. Este tipo de código suele ser más difícil de modificar, más difícil de extender, más difícil de remodelar para hacer algo que originalmente no estaba destinado a hacer. Dicho esto, demasiadas personas son demasiado dogmáticas sobre esto. – Eddie
En realidad, la función 'atan2' mide los radianes del ángulo de un * punto único * al eje x positivo. En otras palabras, no debería tomar dos argumentos numéricos en primer lugar, debería tomar un argumento de un solo punto. Lo cual, en términos OO, podría modelarse como un método en un objeto puntual. –
La orientación a objetos se trata de tres cosas :
- mensajería,
- local de retención y protección y ocultamiento de estado del proceso, y
- extrema de todas las cosas de enlace tardío
de los tres. , el más importante es mensajes.
Los métodos estáticos infringen al menos la mensajería y la vinculación tardía.
La idea de mensajes significa que en OO, el cálculo se realiza mediante redes de objetos autónomos que se envían mensajes entre sí. El envío de un mensaje es el único forma de comunicación/cálculo.
Los métodos estáticos no hacen eso. No están asociados con ningún objeto. Realmente no son métodos en absoluto, según la definición habitual. En realidad son solo procedimientos. No hay diferencia entre un método estático de Java Foo.bar
y una subrutina BASIC FOO_BAR
.
En cuanto a la vinculación tardía: un nombre más moderno para eso es envío dinámico. Los métodos estáticos violan eso, también, de hecho, incluso está en su propio nombre: métodos estáticos.
Los métodos estáticos rompen algunas propiedades muy agradables de la orientación a objetos. Por ejemplo, los sistemas orientados a objetos son automáticamente seguros para las capacidades con objetos que actúan como capacidades. Los métodos estáticos (o realmente cualquier estática, ya sea estado estático o métodos estáticos) rompen esa propiedad.
También puede ejecutar cada objeto en paralelo en su propio proceso, ya que solo se comunican a través de mensajes, lo que proporciona una simultaneidad trivial. (Como Actors, básicamente, lo cual no debería ser demasiado sorprendente, ya que Carl Hewitt creó el Actor Model basado en Smalltalk-71, y Alan Kay creó Smalltalk-71 parcialmente basado en PLANNER, que a su vez fue creado por Carl Hewitt. La estrecha relación entre actores y objetos está lejos de ser una coincidencia, de hecho, son esencialmente uno y el mismo.) De nuevo, los estáticos (ambos métodos estáticos, y especialmente el estado estático) rompen esa bonita propiedad.
Esta es también una excelente respuesta. Ojalá pudiera aceptar más de uno. Gracias. – Mike
Los métodos estáticos causan un acoplamiento apretado, lo cual es una violación del buen diseño orientado a objetos. El acoplamiento estricto del código de llamada y el código dentro del método estático no se puede evitar a través de la Inversión de Dependencia porque los métodos estáticos no son compatibles con las técnicas de diseño orientadas a objetos como la herencia y el polimorfismo.
Además, los métodos estáticos son difíciles de probar debido a estas dependencias estrechamente acopladas, que a menudo conducen a una infraestructura de terceros de la que el código depende, como una base de datos, y hace que sea muy difícil cambiar el comportamiento sin funcionar realmente. en y cambiando el código.
Los métodos estáticos no se consideran buenas prácticas OO debido a razones siguientes:
1) impide Re-usabilidad:
Los métodos estáticos no pueden ser sobreescritos. No se puede usar en la interfaz.
2) duración de los objetos es muy larga:
Los métodos estáticos permanecen en la memoria durante un tiempo de registro y su recolección de basura lleva mucho tiempo. Los desarrolladores no tienen control sobre la destrucción o creación de variables estáticas. El uso excesivo de variables estáticas puede provocar el desbordamiento de la memoria.
3) Además, algunos otros puntos:
no respeta la encapsulación porque objeto does't permanecen en el control completo de su estado. No sigue conceptos como Inversión de control, acoplamiento flojo, inyección de dependencia, etc.
- 1. ¿Se consideran iframes 'mala práctica'?
- 2. ¿Por qué no puedo declarar métodos estáticos en una interfaz?
- 3. Métodos estáticos de Python, ¿por qué?
- 4. ¿Por qué los marcadores de posición, como el primero o el último, en una enumeración se consideran una mala práctica?
- 5. ¿Por qué los métodos de la clase Math están estáticos?
- 6. ¿Por qué los subprocesos del sistema operativo se consideran caros?
- 7. ¿Qué es mejor? Los métodos estáticos o métodos de instancia
- 8. ¿Por qué los métodos Array.Sort() y Array.IndexOf() son estáticos?
- 9. ¿Los objetos inmutables son una buena práctica?
- 10. ¿Por qué algunos (null) no se consideran ninguno?
- 11. Invocación de métodos no estáticos de una clase
- 12. ¿Por qué tienen todos los métodos/variables estáticos en una clase no estática?
- 13. ¿Es una buena práctica escribir métodos que devuelvan el vacío?
- 14. ¿Por qué no se permite sobrecargar los métodos dentro de los métodos (por ejemplo, cierres sobrecargados)?
- 15. Los métodos estáticos en C++
- 16. ¿Por qué no se pueden inicializar campos no estáticos dentro de las estructuras?
- 17. ¿Los constructores protegidos se consideran buenas prácticas?
- 18. Pruebas unitarias: ¿es una buena práctica tener afirmaciones en los métodos de configuración?
- 19. ¿Por qué una clase interna no estática no puede tener miembros estáticos (campos y métodos)?
- 20. Uso de métodos estáticos privados
- 21. ¿Por qué los métodos de interfaz no pueden ser "estáticos" y "finales"?
- 22. ¿Por qué los repositorios de datos no son estáticos?
- 23. ¿Por qué utilizar un singleton en lugar de métodos estáticos?
- 24. ¿Por qué los sub repositorios mercuriales se consideran una característica de último recurso?
- 25. Desventajas de los métodos estáticos en PHP
- 26. Análisis de hilos estáticos: ¿Buena idea?
- 27. ¿Los métodos estáticos se compilan con entusiasmo (JIT)?
- 28. ¿Por qué los métodos estáticos deben ser incluidos en una clase?
- 29. ¿Por qué no se resuelven estos métodos?
- 30. ¿Qué significa redefinir los métodos estáticos en Java?
No estoy seguro de que "no tan puro" se asocie al instante con una mala práctica. – mellowsoon
No es una mala práctica. Simplemente no es una buena práctica, según el autor. – Mike
¿El autor no da ningún razonamiento? –