clases - objetos en scala
¿Por qué los objetos singleton están más orientados a objetos? (7)
Es una cosa de marketing, realmente. Considera dos ejemplos:
class foo
static const int bar = 42;
end class
class superfoo
Integer bar = ConstInteger.new(42);
end class
Ahora, ¿cuáles son las diferencias observables aquí?
- en un lenguaje de buen comportamiento, el almacenamiento adicional creado es el mismo.
- Foo.bar y Superfoo.bar tienen exactamente las mismas firmas, acceso, etc.
- Superfoo.bar puede asignarse de manera diferente, pero eso es un detalle de implementación
Me recuerda las guerras religiosas de hace 20 años sobre si C ++ o Java estaban "realmente" orientados a objetos, ya que después de todos los dos tipos primitivos expuestos que no son "realmente" objetos, entonces, por ejemplo, no se puede heredar de int
pero puede de Integer
.
En Programación en Scala: una guía completa paso a paso , el autor dijo:
Una forma en que Scala está más orientado a objetos que Java es que las clases en Scala no pueden tener miembros estáticos. En cambio, Scala tiene objetos singleton.
¿Por qué un objeto singleton más orientado a objetos? ¿De qué sirve no usar miembros estáticos, sino objetos únicos?
Está más orientado a objetos en el sentido de que dada una clase de Scala, cada llamada de método es una llamada de método a ese objeto. En Java, los métodos estáticos no interactúan con el estado del objeto.
De hecho, dado un objeto a
de una clase A
con el método estático m()
, se considera una mala práctica llamar a am()
. En su lugar, se recomienda llamar a Am()
(creo que Eclipse te dará una advertencia). Los métodos estáticos de Java no se pueden anular, simplemente se pueden ocultar con otro método:
class A {
public static void m() {
System.out.println("m from A");
}
}
public class B extends A {
public static void m() {
System.out.println("m from B");
}
public static void main(String[] args) {
A a = new B();
a.m();
}
}
¿Qué será am()
imprimir?
En Scala, debería pegar los métodos estáticos en los objetos acompañantes A y B, y la intención sería más clara, ya que se referiría explícitamente al compañero A o B.
Agregar el mismo ejemplo en Scala:
class A
object A {
def m() = println("m from A")
}
class B extends A
object B {
def m() = println("m from B")
def main(args: Array[String]) {
val a = new B
A.m() // cannot call a.m()
}
}
Hay alguna diferencia que puede ser importante en algunos escenarios. En Java, no puede anular el método estático, por lo tanto, si tuviera clases con métodos estáticos, no podría personalizar ni anular parte de su comportamiento. Si utilizó un objeto singleton, podría simplemente conectar un singleton creado a partir de la subclase.
Intentando por el "panorama general"; la mayoría de esto se ha cubierto en otras respuestas, pero no parece haber una sola respuesta integral que lo junte todo y se una a los puntos. Así que aquí va ...
Los métodos estáticos en una clase no son métodos en un objeto, esto significa que:
- Los miembros estáticos no se pueden heredar de una clase / rasgo principal
- Los miembros estáticos no se pueden usar para implementar una interfaz
Los miembros estáticos de una clase no se pueden pasar como argumento para alguna función
(y debido a los puntos anteriores ...)
- Los miembros estáticos no pueden ser anulados
- Los miembros estáticos no pueden ser polimórficos
El objetivo de los objetos es que pueden heredar de los objetos principales, implementar interfaces y pasar como argumentos: los miembros estáticos no tienen ninguna de estas propiedades, por lo que no están realmente orientados a objetos, son poco más que un espacio de nombres.
Los objetos Singleton, por otro lado, son miembros de pleno derecho de la comunidad de objetos.
Otra propiedad muy útil de singletons es que pueden cambiarse fácilmente en algún momento posterior para que no sean singletons, esta es una refactorización particularmente dolorosa si comienzas desde métodos estáticos.
Imagine que diseñó un programa para imprimir direcciones e interacciones representadas con la impresora a través de métodos estáticos en alguna clase, luego desea agregar una segunda impresora y permitir que el usuario elija cuál usará ... No lo haría ¡No será una experiencia divertida!
Los objetos Singleton se comportan como clases porque pueden extender / implementar otros tipos.
No se puede hacer eso en Java con solo clases estáticas: es bastante azúcar sobre el patrón singleton de Java con una getInstance
que permite (al menos) espacios de nombres / identificadores estables más bonitos y oculta la distinción.
Para miembros estáticos, no hay ningún objeto . La clase realmente solo es un espacio de nombres.
En un singleton, siempre hay al menos un objeto.
Honestamente, está dividiendo los pelos.
Sugerencia: se llama programación orientada a objetos .
Seriamente.
Tal vez me esté perdiendo algo fundamentalmente importante, pero no veo de qué se trata el alboroto: los objetos están más orientados a objetos que los no objetos porque son objetos. ¿Eso realmente necesita una explicación?
Nota: Aunque seguro suena así, realmente no estoy tratando de sonar presumido aquí. Miré todas las otras respuestas y las encontré terriblemente confusas. Para mí, es obvio que los objetos y métodos están más orientados a objetos que los espacios de nombres y los procedimientos (que son realmente los "métodos" estáticos) por la definición misma de "orientado a objetos".
Una alternativa para tener objetos singleton sería hacer clases ellos mismos objetos, como por ejemplo, Ruby, Python, Smalltalk, Newspeak do.