Tengo cierta experiencia en el desarrollo con Java, Javascript y PHP.
Estoy leyendo Microsoft Visual C # 2010 paso a paso, y creo que es un muy buen libro sobre cómo presentarle el lenguaje C #.
Parece que tengo problemas para entender la palabra clave estática. Por lo que entiendo hasta aquí, si una clase se declara estática, todos los métodos y variables tienen que ser estáticos. El método principal siempre es un método estático, por lo que en la clase en la que existe el método principal, todas las variables y métodos se declaran estáticos si tiene que llamarlos en el método principal. También he notado que para llamar a un método estático desde otra clase no es necesario crear un objeto del que pueda usar el nombre de la clase.
Pero, ¿cuál es el propósito real de la palabra clave estática? ¿Cuándo debo declarar variables estáticas y métodos?
fuente
Respuestas:
La palabra clave 'estática' en C # se refiere a algo en la clase, o la clase misma, que se comparte entre todas las instancias de la clase. Por ejemplo, se puede acceder a un campo marcado como estático desde todas las instancias de esa clase a través del nombre de la clase.
Puedo decir honestamente que nunca he usado una clase marcada como estática con la excepción de crear métodos de extensión ( Tutorial rápido sobre métodos de extensión ).
De todos modos, hay patrones de diseño específicos para utilizar métodos estáticos, como el patrón de fábrica y el patrón singleton , pero lo importante a recordar es que los métodos y constructores estáticos no tratan con ninguna instancia específica de una clase (a menos que pase una), típicamente para hacer cálculos o para hacer una comparación entre objetos. El método "Principal" al que se refiere es siempre estático, pero para verlo desde un punto de vista diferente, consulte este artículo .
Para seguir con esto, así es como se llama la diferencia entre métodos estáticos y instanciados, campos y propiedades.
Además, consulte esta publicación para obtener una visión más profunda de las clases estáticas.
fuente
Aquí está la forma de explicarlo de Joshua Bloch, que encuentro brillante como la mayoría de lo que dice (sí, soy un fanático de Joshua Bloch :)). Esto se cita de memoria.
Imagine que una clase es el equivalente de un plano para una casa. Imagínese entonces que una casa está en el plano como una instancia de la clase es para la clase. Puede tener una clase (blue-print) y múltiples instancias (casas) creadas a partir de ella.
Ahora, el sentido común dicta que la mayoría de las funciones / comportamientos que una casa (instancia) puede tener / hacer, a pesar de que se declaren en el plano, no se pueden usar hasta que una casa (instancia) real esté hecha de ese azul -print (clase). Por ejemplo, su plano puede contener el lugar donde deben ir las luces y las bombillas, pero no tiene forma de hacer que funcionen en el plano, debe construir la casa para poder para encender y apagar el interruptor de la luz y encender y apagar ciertas bombillas.
Sin embargo, es posible que tenga un comportamiento que sea aplicable directamente al plano y que pueda usar / acceder directamente en el plano sin necesidad de hacer una casa real con ese plano. Imagine que su plano tiene un botón que, al presionarlo, mostrará la huella de la casa contenida en ese plano (calculando todas las longitudes de las paredes y demás). Obviamente, PODRÍAS construir una casa primero y luego medir midiendo su huella, pero puedes hacerlo solo con el plano, por lo que sería más útil tener este comportamiento implementado en el plano. Tal botón incrustado de impresión azul que calcula la huella de la casa es el equivalente a tener una función estática en una clase.
fuente
Blueprint
clase que implementa la funcionalidad del plano, incluida la capacidad de calcular la huella de la casa expresada por el plano. Esta instancia de plan se alimenta a unaBuilder
(a su vez, probablemente una instancia), que a su vez hace lo necesario para construir y generar un número potencialmente arbitrario deBuilding
instancias basado en un plan.Mirándolo de esta manera me ayuda:
En cuanto a cuándo usar la palabra clave estática:
fuente
"Looking at it this way helps"
él. Lo encuentras extraño porque no es exactamente cierto, pero puedes pensarlo así si quieres. ¿Conoces el modelo Bohr? Es un conjunto de reglas e ideas sobre cómo los átomos y los electrones interactúan entre sí. El modelo funciona según lo que hagas, pero no es la realidad.static
incluso si no utiliza propiedades locales. Hacer cosasstatic
puede agregar acoplamiento a los clientes porque tienen que abordar la clase directamente. Por ejemplo, esto puede dificultar la prueba unitaria con burla.La explicación más simple --- Estática => Solo existirá una copia por entorno.
Por lo tanto, dentro de una VM o CLR solo habrá una copia de una clase estática y cualquier otra clase que haga referencia a ella tendrá que compartir sus métodos y datos con todas las demás clases que la hagan referencia.
Para una variable estática, solo habrá una instancia de esta variable en el entorno de tiempo de ejecución, sin importar cuántas copias de la clase propietaria se creen cuando hagan referencia a una variable estática, todas harán referencia a la misma pieza de almacenamiento.
fuente
Los miembros estáticos están asociados con la Clase, no con ninguna instancia de esa Clase.
Como estamos hablando de .Net, considere la clase String , en particular los métodos Split y Join .
Split es un método de instancia . Cree una variable de cadena, asígnele un valor y puede llamar a Split () en esa variable / valor y recuperar una matriz de "bits":
Entonces, por ejemplo, los métodos, el valor contenido dentro de la instancia de clase dada es importante .
Unirse es un método estático . OK, se produce una cadena resultado cuando se les da un delimitador y una matriz de cadenas para masticar, por lo que es "algo que ver con" la clase String, pero es no asociado a ningún particular, el valor de ninguna instancia String (de hecho, valores de instancia son no disponible para métodos estáticos).
En otros idiomas, el método Join podría haberse "pegado" a la clase Array (o, quizás mejor, a una clase StringArray) pero Nuestros amigos en Redmond decidieron que era más "relevante" para la clase String, por lo que lo pusieron allí .
Otra alternativa podría haber sido tener un método Join de instancia , donde el valor contenido dentro de String [instancia de clase] usamos como delimitador de unión, algo así como:
fuente
La
static
palabra clave puede ser un poco difícil de entender para los novatos. Su propósito principal es identificar a un miembro de la clase como no perteneciente a una sola instancia de la clase, sino a la clase misma.Sin entrar en demasiados detalles, C # (y Java) imponen rígidamente el ideal orientado a objetos de que todo el código y los datos deben pertenecer a un objeto y, por lo tanto, su alcance, visibilidad y vida útil son limitados. En general, esa es la mejor práctica donde se aplica el principio fundamental de un objeto que representa algo del mundo real. Sin embargo, no siempre es así; a veces lo que necesita es una función o variable a la que pueda acceder desde cualquier parte del código, sin requerir que pase una referencia a un objeto que lo contiene, y con la garantía de que los datos que está viendo o cambiando es exactamente lo que todos más está tratando, y no una copia del mismo que pertenece a una instancia diferente de un objeto.
Tal comportamiento estaba disponible en C y C ++ en la forma de la función o variable "global", que no estaba encapsulada en un objeto. Por lo tanto, como compromiso, C # y Java admiten "alcance estático", un punto intermedio entre el código verdaderamente global sin objeto principal y los miembros de instancia de alcance limitado.
Cualquier "miembro de código" (función, propiedad, campo) declarado como
static
entra en el alcance a partir de la primera línea de lamain()
función del programa , y no lo abandona hastamain()
que finaliza la función. En inglés simple, existe un miembro estático y se puede usar mientras el programa se esté ejecutando. Además, los miembros estáticos se invocan llamándolos como miembros del tipo en sí, no como miembros de ninguna instancia de ese tipo:Esto hace que los miembros estáticos sean visibles para cualquier código que tenga conocimiento del tipo, ya sea que conozcan o no alguna instancia del mismo.
Para responder a su pregunta, el beneficio principal de marcar algo como estático es que se hace visible donde se conoce el tipo en sí, independientemente de si el código consumidor tiene o puede obtener una instancia del objeto que lo contiene. También hay un ligero beneficio de rendimiento; Debido a que el método tiene un alcance estático, solo puede acceder a otros miembros estáticos (de la misma clase u otros), y todo lo que se pase como parámetro. Por lo tanto, el tiempo de ejecución no tiene que resolver ninguna referencia a la instancia actual del objeto contenedor, ya que normalmente tendría que hacerlo con un método de instancia para proporcionar información de estado específica del contexto.
Las clases enteras también se pueden marcar como estáticas; Al hacerlo, le dice al compilador que la declaración de clase consistirá únicamente en miembros estáticos y, por lo tanto, no se puede crear una instancia. Esta es una manera fácil de garantizar que haya una, y solo una, copia de un objeto en la memoria; hacer que la clase y todo lo que contiene sea estática. Sin embargo, es muy raro que esta sea la mejor solución para tal necesidad. En una situación donde se requiere exactamente una copia de un conjunto de datos, el "singleton" generalmente se recomienda en su lugar; Esta es una clase no estática, que utiliza un descriptor de acceso estático y un constructor no público para proporcionar acceso a una sola instancia de sí mismo. Teóricamente, un singleton proporciona los mismos beneficios que una clase completamente estática, pero con la capacidad adicional de usar la clase de una manera orientada a objetos y basada en instancias.
fuente