Tenho alguma experiência no desenvolvimento de Java, Javascript e PHP.
Estou lendo o Microsoft Visual C # 2010 passo a passo, que considero um livro muito bom sobre como apresentar a linguagem C #.
Parece que estou tendo problemas para entender a palavra-chave estática. Pelo que entendi até agora, se uma classe é declarada estática, todos os métodos e variáveis devem ser estáticos. O método principal sempre é um método estático, portanto, na classe em que o método principal existe, todas as variáveis e métodos são declarados estáticos se você precisar chamá-los no método principal. Também notei que, para chamar um método estático de outra classe, você não precisa criar um objeto que possa usar o nome da classe.
Mas qual é o objetivo real da palavra-chave estática? Quando devo declarar métodos e variáveis estáticas?
fonte
Respostas:
A palavra-chave 'estática' em C # refere-se a algo na classe, ou a própria classe, que é compartilhada entre todas as instâncias da classe. Por exemplo, um campo marcado como estático pode ser acessado de todas as instâncias dessa classe através do nome da classe.
Posso dizer honestamente que nunca usei uma classe marcada como estática, com exceção da criação de métodos de extensão ( Tutorial rápido sobre métodos de extensão ).
De qualquer forma, existem padrões de design específicos para a utilização de métodos estáticos, como padrão de fábrica e padrão singleton , mas o importante é lembrar que métodos e construtores estáticos não lidam com nenhuma instância específica de uma classe (a menos que você passe uma) normalmente para fazer cálculos ou fazer uma comparação entre objetos. O método "Principal" ao qual você está se referindo é sempre estático, mas para vê-lo de um ponto de vista diferente, consulte este artigo .
Para acompanhar, aqui está como é chamada a diferença entre métodos, campos e propriedades estáticos e instanciados.
Além disso, confira este post para uma análise mais profunda das classes estáticas.
fonte
Aqui está a maneira de Joshua Bloch explicar, que eu acho brilhante como quase tudo o que ele diz (sim, eu sou fã de Joshua Bloch :)). Isso é citado na memória.
Imagine que uma classe é o equivalente a uma planta para uma casa. Imagine então que uma casa é do tipo blueprint, como uma instância da classe é para a classe. Você pode ter uma classe (blueprint) e várias instâncias (casas) criadas a partir dela.
Agora, o senso comum determina que a maioria das funções / comportamentos que uma casa (instância) pode ter / realizar, mesmo que sejam declaradas na planta, não pode ser usada até que uma casa real (instância) seja feita desse azul -print (classe). Assim, seu projeto pode conter nele o lugar onde as luzes e as lâmpadas devem ir, mas você não tem como fazer isso funcionar no projeto, você precisa construir a casa para poder para ligar e desligar o interruptor e ligar e desligar determinadas lâmpadas.
No entanto, você pode ter algum comportamento aplicável diretamente ao blueprint e que você pode usar / acessar diretamente no blueprint sem precisar criar uma casa real com esse blueprint. Imagine que sua planta azul tenha um botão que, ao pressionar, exibirá a área da casa contida nessa planta (calculando todos os comprimentos das paredes e outras). Obviamente, você PODE construir uma casa primeiro e depois medir sua pegada, mas você pode fazer isso apenas com a planta azul, por isso seria mais útil ter esse comportamento implementado na planta. Esse botão incorporado de planta azul que calcula a área ocupada da casa é o equivalente a ter uma função estática em uma classe.
fonte
Blueprint
classe que implementa a funcionalidade do blueprint, incluindo a capacidade de calcular a pegada da casa expressa pelo blueprint. Essa instância do blueprint é então alimentada a umaBuilder
(que por sua vez provavelmente é uma instância), que, por sua vez, faz o necessário para construir e gerar um número potencialmente arbitrário deBuilding
instâncias com base em um blueprint.Olhar dessa maneira me ajuda a:
Quanto a quando usar a palavra-chave estática:
fonte
"Looking at it this way helps"
ele. Você acha estranho porque não é exatamente verdade, mas pode pensar assim se quiser. Você conhece o modelo Bohr? É um apresenta um conjunto de regras e idéias de como átomos e elétrons interagem entre si. O modelo funciona dependendo do que você faz, mas não é a realidade.static
mesmo que não use propriedades locais. Fazer coisasstatic
pode adicionar acoplamento aos clientes porque eles precisam abordar a classe diretamente. Por exemplo, isso pode dificultar o teste de unidade com simulação.Explicação mais simples --- Estática => Somente uma cópia existirá por ambiente.
Portanto, dentro de uma VM ou CLR, haverá apenas uma cópia de uma classe estática e, qualquer outra classe de referência terá que compartilhar seus métodos e dados com todas as outras classes de referência.
Para uma variável estática, haverá apenas uma instância dessa variável no ambiente de tempo de execução, não importa quantas cópias da classe proprietária sejam criadas quando fizerem referência a uma variável estática, todas elas farão referência ao mesmo pedaço de armazenamento.
fonte
Membros estáticos estão associados à classe, não a nenhuma instância dessa classe.
Como estamos falando de .Net, considere a classe String , em particular os métodos Split e Join .
Split é um método de instância . Crie uma variável String, forneça um valor e você pode chamar Split () nessa variável / valor e recuperar uma matriz de "bits":
Portanto, por exemplo, métodos, o valor mantido dentro da instância de classe especificada é importante .
Join é um método estático . OK, ele produz uma String resultado quando recebe um delimitador e uma matriz de String para mastigar, por isso é "algo a ver com" a classe String, mas é não associado a qualquer determinado valor em qualquer instância String (de fato, valores de instância são não disponível para métodos estáticos).
Em outros idiomas, o método Join pode ter sido "preso" à classe Array (ou, talvez melhor, uma classe StringArray), mas Our Friends in Redmond decidiu que era mais "relevante" para a classe String, então eles a colocaram lá .
Outra alternativa poderia ter sido um método Join de instância , em que o valor mantido dentro da String [instância de classe] nos era usado como delimitador de junção, algo como:
fonte
A
static
palavra-chave pode ser um pouco difícil de entender para iniciantes. Seu objetivo principal é identificar um membro da classe como não pertencente a nenhuma instância única da classe, mas à própria classe.Sem entrar em muitos detalhes, o C # (e Java) impõe rigidamente o ideal orientado a objetos de que todo o código e dados devem pertencer a um objeto e, portanto, é limitado em escopo, visibilidade e tempo de vida. Geralmente, é uma prática recomendada sempre que o princípio fundamental de um objeto que representa alguma coisa do mundo real se aplica. No entanto, nem sempre; às vezes, o que você precisa é de uma função ou variável que você possa acessar de qualquer lugar no código, sem exigir que você passe uma referência a um objeto que o contenha e com a garantia de que os dados que você está vendo ou alterando sejam exatamente o que todos else está lidando com, e não uma cópia dele pertencente a uma instância diferente de um objeto.
Esse comportamento estava disponível em C e C ++ na forma da função ou variável "global", que não estava encapsulada em um objeto. Portanto, como compromisso, C # e Java suportam "escopo estático", um ponto intermediário entre código verdadeiramente global sem objeto pai e membros de instância de escopo limitado.
Qualquer "membro do código" (função, propriedade, campo) declarado como
static
entra no escopo a partir da primeira linha damain()
função do programa e não o deixa até que amain()
função seja encerrada. Em inglês simples, um membro estático existe e pode ser usado enquanto o programa estiver em execução. Além disso, os membros estáticos são invocados chamando-os como membros do próprio tipo, não membros de nenhuma instância desse tipo:Isso torna os membros estáticos visíveis para qualquer código que tenha conhecimento do tipo, sabendo ou não sobre uma única instância dele.
Para responder sua pergunta, o principal benefício de marcar algo como estático é que ele se torna visível onde quer que o próprio tipo seja conhecido, independentemente de o código consumidor ter ou poder obter uma instância do objeto que o contém. Há também um pequeno benefício de desempenho; como o método está no escopo estático, ele pode acessar apenas outros membros estáticos (da mesma classe ou de outros) e o que for passado como parâmetro. Portanto, o tempo de execução não precisa resolver nenhuma referência à instância atual do objeto que contém, como normalmente seria necessário para um método de instância para fornecer informações de estado específicas do contexto.
Classes inteiras também podem ser marcadas como estáticas; ao fazer isso, você informa ao compilador que a declaração de classe consistirá apenas em membros estáticos e, portanto, não poderá ser instanciada. Essa é uma maneira fácil de garantir que exista uma e apenas uma cópia de um objeto na memória; torne a classe e tudo nela estático. No entanto, é muito raro que esta seja a melhor solução para essa necessidade. Em uma situação em que exatamente uma cópia de um conjunto de dados é necessária, o "singleton" é normalmente recomendado; essa é uma classe não estática, que usa um acessador estático e um construtor não público para fornecer acesso a uma única instância. Teoricamente, um singleton oferece os mesmos benefícios de uma classe totalmente estática, mas com a capacidade adicional de usar a classe de uma maneira orientada a objeto e baseada em instância.
fonte