Por que não é possível substituir métodos estáticos?
Se possível, use um exemplo.
java
static
overriding
static-methods
sgokhales
fonte
fonte
Parent p = new Child()
e, em seguida,p.childOverriddenStaticMethod()
o compilador resolverá o problemaParent.childOverriddenStaticMethod()
observando o tipo de referência.Respostas:
A substituição depende de ter uma instância de uma classe. O objetivo do polimorfismo é que você pode subclassificar uma classe e os objetos que implementam essas subclasses terão comportamentos diferentes para os mesmos métodos definidos na superclasse (e substituídos nas subclasses). Um método estático não está associado a nenhuma instância de uma classe, portanto o conceito não é aplicável.
Havia duas considerações que influenciaram o design do Java. Uma era a preocupação com o desempenho: havia muitas críticas ao Smalltalk por ser muito lento (coleta de lixo e chamadas polimórficas fazendo parte disso) e os criadores de Java estavam determinados a evitar isso. Outra foi a decisão de que o público-alvo para Java eram desenvolvedores de C ++. Fazer com que os métodos estáticos funcionem da mesma maneira que eles tiveram o benefício de familiaridade para os programadores de C ++ e também foi muito rápido, porque não há necessidade de esperar até o tempo de execução para descobrir qual método chamar.
fonte
objects
) permite sobrecarregar os métodos.obj.staticMethod()
) - que é permitido e usa os tipos de tempo de compilação. Quando a chamada estática está em um método não estático de uma classe, o objeto "atual" pode ser um tipo derivado da classe - mas os métodos estáticos definidos nos tipos derivados não são considerados (eles estão no tipo de tempo de execução hierarquia).Pessoalmente, acho que essa é uma falha no design do Java. Sim, sim, entendo que métodos não estáticos estão anexados a uma instância, enquanto métodos estáticos estão anexados a uma classe, etc. etc. Ainda assim, considere o seguinte código:
Este código não funcionará conforme o esperado. Ou seja, os funcionários especiais recebem um bônus de 2%, assim como os funcionários regulares. Mas se você remover as "estáticas", os funcionários especiais recebem um bônus de 3%.
(É certo que este exemplo é um estilo de codificação ruim, pois na vida real você provavelmente desejaria que o multiplicador de bônus estivesse em um banco de dados em algum lugar, em vez de codificado. de código irrelevante ao ponto.)
Parece-me bastante plausível que você queira tornar estático getBonusMultiplier. Talvez você queira exibir o multiplicador de bônus para todas as categorias de funcionários, sem precisar ter uma instância de funcionário em cada categoria. Qual seria o sentido de procurar exemplos de exemplos? E se estamos criando uma nova categoria de funcionário e ainda não temos nenhum funcionário atribuído a ela? Isso é logicamente uma função estática.
Mas isso não funciona.
E sim, sim, posso pensar em várias maneiras de reescrever o código acima para fazê-lo funcionar. Meu argumento não é que ele crie um problema insolúvel, mas que crie uma armadilha para o programador incauto, porque a linguagem não se comporta como eu acho que uma pessoa razoável esperaria.
Talvez se eu tentasse escrever um compilador para uma linguagem OOP, veria rapidamente por que seria difícil ou impossível implementá-lo para que as funções estáticas possam ser substituídas.
Ou talvez haja alguma boa razão pela qual o Java se comporte dessa maneira. Alguém pode apontar uma vantagem para esse comportamento, alguma categoria de problema que é facilitada por isso? Quero dizer, não me aponte apenas para a especificação da linguagem Java e diga "veja, isso está documentado como ela se comporta". Eu sei disso. Mas há uma boa razão pela qual DEVE se comportar dessa maneira? (Além do óbvio "fazê-lo funcionar direito era muito difícil" ...)
Atualizar
@ VicKirk: Se você quer dizer que esse é um "design ruim" porque não se encaixa na maneira como o Java lida com a estática, minha resposta é: "Bem, claro, é claro". Como eu disse no meu post original, ele não funciona. Mas se você quer dizer que é um projeto ruim, no sentido de que haveria algo de fundamentalmente errado com uma linguagem em que isso funcionasse, ou seja, onde a estatística pudesse ser substituída como funções virtuais, isso introduziria de alguma forma uma ambiguidade ou seria impossível implementar eficientemente ou algo assim, respondo: "Por quê? O que há de errado com o conceito?"
Eu acho que o exemplo que dou é uma coisa muito natural de se querer fazer. Eu tenho uma classe que tem uma função que não depende de nenhum dado da instância e que eu poderia razoavelmente querer chamar independente de uma instância, além de querer chamar de dentro de um método de instância. Por que isso não deve funcionar? Eu já enfrentei essa situação várias vezes ao longo dos anos. Na prática, eu contorno isso, tornando a função virtual e, em seguida, criando um método estático cujo único objetivo na vida é ser um método estático que transmite a chamada para o método virtual com uma instância fictícia. Parece uma maneira muito indireta de chegar lá.
fonte
someStatic()
e B estende A,B.someMethod()
vincula -o ao método em A. Se eu adicionar posteriormentesomeStatic()
a B, o código de chamada ainda será chamadoA.someStatic()
até eu recompilar o código de chamada. Também me surpreendeu quebInstance.someStatic()
use o tipo declarado de bInstance, não o tipo de tempo de execução, porque ele liga no compile, não no link, portanto,A bInstance; ... bInstance.someStatic()
chama A.someStatic () se houver B.someStatic ().A resposta curta é: é inteiramente possível, mas o Java não faz isso.
Aqui está um código que ilustra o estado atual das coisas em Java:
Arquivo
Base.java
:Arquivo
Child.java
:Se você executar isso (eu fiz em um Mac, no Eclipse, usando Java 1.6), você obtém:
Aqui, os únicos casos que podem ser uma surpresa (e de que trata a questão) parecem ser o primeiro caso:
"O tipo de tempo de execução não é usado para determinar quais métodos estáticos são chamados, mesmo quando chamados com uma instância de objeto (
obj.staticMethod()
)."e o último caso:
"Ao chamar um método estático de dentro de um método de objeto de uma classe, o método estático escolhido é aquele acessível pela própria classe e não pela classe que define o tipo de objeto em tempo de execução."
Chamando com uma instância de objeto
A chamada estática é resolvida em tempo de compilação, enquanto uma chamada de método não estático é resolvida em tempo de execução. Observe que, embora os métodos estáticos sejam herdados (do pai), eles não são substituídos (pelo filho). Isso poderia ser uma surpresa se você esperasse o contrário.
Chamando de dentro de um método de objeto
As chamadas de método de objeto são resolvidas usando o tipo de tempo de execução, mas as chamadas de método estático ( classe ) são resolvidas usando o tipo de tempo de compilação (declarado).
Mudando as regras
Para alterar essas regras, para que a última chamada no exemplo chamado
Child.printValue()
, as chamadas estáticas precisem ser fornecidas com um tipo em tempo de execução, em vez de o compilador resolver a chamada em tempo de compilação com a classe declarada do objeto (ou contexto). As chamadas estáticas podem então usar a hierarquia de tipos (dinâmicos) para resolver a chamada, assim como as chamadas de método de objeto fazem hoje.Isso seria facilmente possível (se alterássemos o Java: -O) e não é de todo irracional, no entanto, ele tem algumas considerações interessantes.
A principal consideração é que precisamos decidir quais chamadas de método estático devem fazer isso.
No momento, Java possui essa "peculiaridade" na linguagem em que as
obj.staticMethod()
chamadas são substituídas porObjectClass.staticMethod()
chamadas (normalmente com um aviso). [ Nota:ObjectClass
é o tipo de tempo de compilaçãoobj
.] Esses seriam bons candidatos para substituir dessa maneira, assumindo o tipo de tempo de execução deobj
.Se o fizéssemos, isso tornaria os corpos dos métodos mais difíceis de ler: chamadas estáticas em uma classe pai poderiam potencialmente ser "redirecionadas" dinamicamente . Para evitar isso, teríamos que chamar o método estático com um nome de classe - e isso torna as chamadas mais obviamente resolvidas com a hierarquia de tipos em tempo de compilação (como agora).
As outras maneiras de chamar um método estático são mais complicadas:
this.staticMethod()
devem significar o mesmo queobj.staticMethod()
, usando o tipo de tempo de execução dethis
. No entanto, isso pode causar algumas dores de cabeça nos programas existentes, que chamam métodos estáticos (aparentemente locais) sem decoração (o que é possivelmente equivalente athis.method()
).Então, e as chamadas sem adornos
staticMethod()
? Sugiro que façam o mesmo de hoje e usem o contexto de classe local para decidir o que fazer. Caso contrário, haveria grande confusão. É claro que significa quemethod()
isso significariathis.method()
semethod
era um método não estático eThisClass.method()
semethod
era um método estático. Essa é outra fonte de confusão.Outras considerações
Se mudou este comportamento (e fez chamadas estáticas potencialmente dinamicamente não-local), nós provavelmente quer revisitar o significado de
final
,private
eprotected
como qualificadores emstatic
métodos de uma classe. Teríamos, então todos têm que se acostumar com o fato de queprivate static
epublic final
métodos não foram substituídas, e, portanto, pode ser resolvido de forma segura em tempo de compilação, e são "seguros" para ler como referências locais.fonte
Na verdade, estávamos errados.
Apesar de Java não permitir que você substitua métodos estáticos por padrão, se você examinar minuciosamente a documentação das classes Class e Method em Java, ainda poderá encontrar uma maneira de emular a substituição de métodos estáticos seguindo a seguinte solução alternativa:
Resultado resultante:
o que estávamos tentando alcançar :)
Mesmo se declararmos a terceira variável Carl como RegularEmployee e atribuir a ela uma instância de SpecialEmployee, ainda teremos a chamada do método RegularEmployee no primeiro caso e a chamada do método SpecialEmployee no segundo caso
basta olhar para o console de saída:
;)
fonte
Os métodos estáticos são tratados como globais pela JVM, não estão vinculados a uma instância de objeto.
Conceitualmente, seria possível se você pudesse chamar métodos estáticos de objetos de classe (como em linguagens como Smalltalk), mas não é o caso em Java.
EDITAR
Você pode sobrecarregar o método estático, tudo bem. Mas você não pode substituir um método estático, porque a classe não é um objeto de primeira classe. Você pode usar a reflexão para obter a classe de um objeto em tempo de execução, mas o objeto obtido não é paralelo à hierarquia de classes.
Você pode refletir sobre as aulas, mas isso pára por aí. Você não invoca um método estático usando
clazz1.staticMethod()
, mas usandoMyClass.staticMethod()
. Um método estático não está vinculado a um objeto e, portanto, não há noçãothis
nemsuper
em um método estático. Um método estático é uma função global; como conseqüência, também não há noção de polimorfismo e, portanto, a substituição do método não faz sentido.Mas isso poderia ser possível se
MyClass
fosse um objeto em tempo de execução no qual você invoca um método, como no Smalltalk (ou talvez no JRuby como um comentário sugere, mas não sei nada sobre o JRuby).Ah sim ... mais uma coisa. Você pode invocar um método estático através de um objeto,
obj1.staticMethod()
mas esse açúcar realmente sintático paraMyClass.staticMethod()
e deve ser evitado. Geralmente, gera um aviso no IDE moderno. Não sei por que eles permitiram esse atalho.fonte
clazz2 instanceof clazz1
corretamente, você pode usarclass2.isAssignableFrom(clazz1)
, o que acredito que retornaria verdadeiro no seu exemplo.A substituição do método é possibilitada pelo despacho dinâmico , o que significa que o tipo declarado de um objeto não determina seu comportamento, mas seu tipo de tempo de execução:
Embora ambos
lassie
ekermit
sejam declarados como objetos do tipoAnimal
, seu comportamento (método.speak()
) varia porque o despacho dinâmico vincula apenas a chamada do método.speak()
a uma implementação em tempo de execução - não em tempo de compilação.Agora, é aqui que a
static
palavra - chave começa a fazer sentido: a palavra "estático" é um antônimo de "dinâmico". Portanto, a razão pela qual você não pode substituir os métodos estáticos é porque não há expedição dinâmica nos membros estáticos - porque estática significa literalmente "não dinâmico". Se eles fossem enviados dinamicamente (e, portanto, pudessem ser substituídos), astatic
palavra - chave não faria mais sentido.fonte
Sim. Praticamente Java permite substituir o método estático, e Não, teoricamente, se você substituir um método estático em Java, ele será compilado e executado sem problemas, mas perderá o polimorfismo, que é a propriedade básica do Java. Você lerá em todos os lugares que não é possível tentar compilar e executar. você receberá sua resposta. por exemplo, se você possui a classe Animal e um método estático eat () e você substitui esse método estático em sua subclasse, vamos chamá-lo de cão. Então, quando quer que você atribua um objeto Dog a uma referência animal e chame eat () de acordo com o comando eat Java de Java, deveria ter sido chamado, mas em Substituir estático, o eat () dos animais será chamado.
De acordo com o princípio de polimorfismo de Java, a saída deve ser
Dog Eating
.Mas o resultado foi diferente porque, para oferecer suporte ao polimorfismo, o Java usa a ligação tardia, o que significa que os métodos são chamados apenas no tempo de execução, mas não no caso de métodos estáticos. Nos métodos estáticos, o compilador chama métodos no tempo de compilação e não no tempo de execução, portanto, obtemos métodos de acordo com a referência e não de acordo com o objeto, uma referência a contendo é por isso que 't.
fonte
a substituição é reservada para membros da instância para suportar comportamento polimórfico. membros da classe estática não pertencem a uma instância específica. em vez disso, membros estáticos pertencem à classe e, como resultado, a substituição não é suportada porque as subclasses herdam apenas membros de instância pública e protegida e não membros estáticos. Você pode definir uma fábrica de interface e / ou padrões de design de estratégia para avaliar uma abordagem alternativa.
fonte
Em Java (e em muitas linguagens OOP, mas não posso falar por todos; e algumas não têm estática), todos os métodos têm uma assinatura fixa - os parâmetros e tipos. Em um método virtual, o primeiro parâmetro está implícito: uma referência ao próprio objeto e, quando chamado de dentro do objeto, o compilador adiciona automaticamente
this
.Não há diferença para métodos estáticos - eles ainda têm uma assinatura fixa. No entanto, ao declarar o método estático, você declarou explicitamente que o compilador não deve incluir o parâmetro de objeto implícito no início dessa assinatura. Portanto, qualquer outro código que chama isso não deve tentar colocar uma referência a um objeto na pilha . Se fizesse isso, a execução do método não funcionaria, pois os parâmetros estariam no lugar errado - deslocados por um - na pilha.
Por causa dessa diferença entre os dois; Os métodos virtuais sempre têm uma referência ao objeto de contexto (ou seja
this
), portanto, é possível fazer referência a qualquer coisa dentro da pilha que pertença à instância do objeto. Mas com métodos estáticos, como não há referência passada, esse método não pode acessar nenhuma variável e método de objeto, pois o contexto não é conhecido.Se você deseja que o Java altere a definição para que um contexto de objeto seja passado para todos os métodos, estáticos ou virtuais, em essência você teria apenas métodos virtuais.
Como alguém perguntou em um comentário à operação - qual é o motivo e o propósito de desejar esse recurso?
Não conheço muito o Ruby, como isso foi mencionado pelo OP, fiz algumas pesquisas. Vejo que nas classes Ruby é realmente um tipo especial de objeto e é possível criar (mesmo dinamicamente) novos métodos. Classes são objetos de classe completos em Ruby, eles não estão em Java. Isso é apenas algo que você terá que aceitar ao trabalhar com Java (ou C #). Essas não são linguagens dinâmicas, embora o C # esteja adicionando algumas formas de dinâmica. Na realidade, Ruby não possui métodos "estáticos" até onde pude encontrar - nesse caso, são métodos no objeto de classe singleton. Você pode substituir esse singleton por uma nova classe e os métodos no objeto de classe anterior chamarão aqueles definidos na nova classe (correto?). Portanto, se você chamasse um método no contexto da classe original, ele ainda executaria apenas a estática original, mas chamar um método na classe derivada chamaria métodos da matriz ou subclasse. Interessante e posso ver algum valor nisso. É preciso um padrão de pensamento diferente.
Como você está trabalhando em Java, precisará se ajustar a essa maneira de fazer as coisas. Por que eles fizeram isso? Bem, provavelmente para melhorar o desempenho na época, com base na tecnologia e no entendimento disponíveis. As linguagens de computador estão em constante evolução. Volte o suficiente e não existe OOP. No futuro, haverá outras novas idéias.
EDIT : Mais um comentário. Agora que vejo as diferenças e como desenvolvedor Java / C #, consigo entender por que as respostas que você obtém dos desenvolvedores Java podem ser confusas se você vem de uma linguagem como Ruby. Os
static
métodos Java não são os mesmos que osclass
métodos Ruby . Os desenvolvedores de Java terão dificuldade em entender isso, assim como os que trabalham principalmente com uma linguagem como Ruby / Smalltalk. Eu posso ver como isso também seria muito confuso pelo fato de o Java também usar "método de classe" como outra maneira de falar sobre métodos estáticos, mas esse mesmo termo é usado de maneira diferente por Ruby. Java não possui métodos de classe de estilo Ruby (desculpe); O Ruby não possui métodos estáticos no estilo Java, que são realmente apenas funções de estilo processual antigas, como encontrado em C.By the way - obrigado pela pergunta! Hoje aprendi algo novo para mim sobre métodos de classe (estilo Ruby).
fonte
Bem ... a resposta é NÃO se você pensar da perspectiva de como um método substituído deve se comportar em Java. Mas, você não receberá nenhum erro do compilador se tentar substituir um método estático. Isso significa que, se você tentar substituir, o Java não o impedirá de fazer isso; mas você certamente não obtém o mesmo efeito dos métodos não estáticos. A substituição em Java significa simplesmente que o método específico seria chamado com base no tipo de tempo de execução do objeto e não no tipo de tempo de compilação (que é o caso dos métodos estáticos substituídos). Ok ... alguma suposição pela razão pela qual eles se comportam estranhamente? Como são métodos de classe e, portanto, o acesso a eles sempre é resolvido durante o tempo de compilação, usando apenas as informações do tipo de tempo de compilação.
Exemplo : vamos tentar ver o que acontece se tentarmos substituir um método estático: -
Saída : -
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod
Observe a segunda linha da saída. Se o staticMethod tivesse sido substituído, essa linha deveria ser idêntica à terceira linha, pois estamos chamando o 'staticMethod ()' em um objeto do Runtime Type como 'SubClass' e não como 'SuperClass'. Isso confirma que os métodos estáticos são sempre resolvidos usando apenas suas informações de tipo de tempo de compilação.
fonte
Em geral, não faz sentido permitir a substituição de métodos estáticos, pois não haveria uma boa maneira de determinar qual deles chamar em tempo de execução. Tomando o exemplo Employee, se chamarmos RegularEmployee.getBonusMultiplier () - qual método deve ser executado?
No caso de Java, pode-se imaginar uma definição de linguagem na qual é possível 'substituir' métodos estáticos, desde que sejam chamados por meio de uma instância de objeto. No entanto, tudo o que isso faria é reimplementar métodos de classe regulares, adicionando redundância ao idioma sem realmente adicionar nenhum benefício.
fonte
Ao substituir, podemos criar uma natureza polimórfica, dependendo do tipo de objeto. O método estático não tem relação com o objeto. Portanto, o java não pode suportar a substituição de método estático.
fonte
Gosto e duplico o comentário de Jay ( https://stackoverflow.com/a/2223803/1517187 ).
Concordo que esse é o design ruim do Java.
Muitos outros idiomas suportam a substituição de métodos estáticos, como vemos nos comentários anteriores. Eu sinto que Jay também veio do Delphi para Java como eu.
Delphi (Object Pascal) foi o primeiro idioma a implementar OOP.
É óbvio que muitas pessoas tiveram experiência com esse idioma, pois no passado era o único idioma para escrever produtos comerciais de GUI. E - sim, nós poderíamos no Delphi substituir métodos estáticos. Na verdade, os métodos estáticos no Delphi são chamados de "métodos de classe", enquanto o Delphi tinha o conceito diferente de "métodos estáticos Delphi", que eram métodos com ligação inicial. Para substituir os métodos que você teve que usar ligação tardia, declare a diretiva "virtual". Por isso, foi muito conveniente e intuitivo e eu esperaria isso em Java.
fonte
Que bem fará para substituir os métodos estáticos. Você não pode chamar métodos estáticos por meio de uma instância.
EDIT: Parece que, através de uma supervisão infeliz no design de linguagem, você pode chamar métodos estáticos por meio de uma instância. Geralmente ninguém faz isso. Foi mal.
fonte
variable.staticMethod()
, em vez deClass.staticMethod()
, ondevariable
é uma variável com o tipo declaradoClass
. Eu concordo que é um design de linguagem ruim.A substituição em Java simplesmente significa que o método específico seria chamado com base no tipo de tempo de execução do objeto e não no tipo de tempo de compilação (que é o caso dos métodos estáticos substituídos). Como métodos estáticos são métodos de classe, eles não são métodos de instância; portanto, eles não têm nada a ver com o fato de que referência está apontando para qual Objeto ou instância, porque, devido à natureza do método estático, ele pertence a uma classe específica. Você pode redeclará-lo na subclasse, mas essa subclasse não saberá nada sobre os métodos estáticos da classe pai, porque, como eu disse, é específica apenas para a classe em que foi declarada. Acessá-los usando referências a objetos é apenas uma liberdade extra concedida pelos designers de Java e certamente não devemos pensar em interromper essa prática apenas quando eles a restringirem mais detalhes e exemplo http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html
fonte
Ao substituir, você obtém polimorfismo dinâmico. Quando você diz substituir métodos estáticos, as palavras que você está tentando usar são contraditórias.
Static diz - o tempo de compilação, a substituição é usada para o polimorfismo dinâmico. Ambos têm natureza oposta e, portanto, não podem ser usados juntos.
O comportamento polimórfico dinâmico ocorre quando um programador usa um objeto e acessa um método de instância. O JRE mapeará diferentes métodos de instância de diferentes classes com base no tipo de objeto que você está usando.
Quando você diz substituir métodos estáticos, métodos estáticos que acessaremos usando o nome da classe, que será vinculado no tempo de compilação, para que não haja conceito de vincular métodos em tempo de execução com métodos estáticos. Portanto, o próprio termo "substituir" os métodos estáticos não faz sentido.
Nota: mesmo se você acessar um método de classe com um objeto, o compilador java ainda é inteligente o suficiente para descobrir e fará a vinculação estática.
fonte
Box.createBox
faz mais sentido do queBoxFactory.createBox
e é um padrão inevitável ao precisar verificar a construção de erros sem gerar exceções (os construtores não podem falhar, eles podem apenas matar o processo / lançamento exceção), enquanto um método estático pode retornar nulo em caso de falha ou até mesmo aceitar retornos de chamada de sucesso / erro para escrever algo como haste.bin/codajahati.java .A resposta a esta pergunta é simples, o método ou a variável marcada como estática pertence apenas à classe. Portanto, o método estático não pode ser herdado na subclasse porque eles pertencem apenas à superclasse.
fonte
Solução fácil: use instância singleton. Isso permitirá substituições e herança.
No meu sistema, tenho a classe SingletonsRegistry, que retorna a instância para a classe passada. Se a instância não for encontrada, ela será criada.
Classe de idioma Haxe:
fonte
Singleton.get()
. O registro é apenas sobrecarga de clichê, e impede o GC nas classes.Um método estático, variável, bloco ou classe aninhada pertence à classe inteira e não a um objeto.
Um método em Java é usado para expor o comportamento de um objeto / classe. Aqui, como o método é estático (isto é, o método estático é usado para representar apenas o comportamento de uma classe). Alterar / substituir o comportamento de toda a classe violará o fenômeno de um dos pilares fundamentais da programação orientada a objetos, ou seja, alta coesão . (lembre-se de que um construtor é um tipo especial de método em Java.)
Coesão Alta - Uma classe deve ter apenas um papel. Por exemplo: Uma classe de carro deve produzir apenas objetos de carro e não bicicleta, caminhões, aviões etc. Mas a classe Car pode ter alguns recursos (comportamento) que pertencem apenas a ela mesma.
Portanto, ao projetar a linguagem de programação java. Os designers de linguagem pensaram em permitir que os desenvolvedores mantivessem alguns comportamentos de uma classe apenas para si, tornando um método estático por natureza.
O código da peça abaixo tenta substituir o método estático, mas não encontrará nenhum erro de compilação.
Isso ocorre porque, aqui, não estamos substituindo um método, mas apenas o declarando novamente . Java permite a re-declaração de um método (estático / não estático).
A remoção da palavra-chave estática do método getVehileNumber () da classe Car resultará em erro de compilação. Como estamos tentando alterar a funcionalidade do método estático, que pertence apenas à classe Vehicle.
Além disso, se o getVehileNumber () for declarado como final , o código não será compilado, uma vez que a palavra-chave final impede o programador de declarar novamente o método.
No geral, isso depende de designers de software para onde usar os métodos estáticos. Pessoalmente, prefiro usar métodos estáticos para executar algumas ações sem criar nenhuma instância de uma classe. Em segundo lugar, ocultar o comportamento de uma classe do mundo exterior.
fonte
Aqui está uma explicação simples. Um método estático está associado a uma classe, enquanto um método de instância está associado a um objeto específico. As substituições permitem chamar a implementação diferente dos métodos substituídos associados ao objeto específico. Portanto, é contra-intuitivo substituir o método estático que nem sequer está associado aos objetos, mas à própria classe em primeiro lugar. Portanto, métodos estáticos não podem ser substituídos com base no objeto que o está chamando, ele sempre será associado à classe em que foi criado.
fonte
public abstract IBox createBox();
interface IBox interna? Box pode implementar o IBox para substituir o createBox e fazer com que a criação do objeto resulte em um IBox válido; caso contrário, retorne um valor nulo. Os construtores não podem retornar "nulo" e, portanto, você é forçado a (1) usar exceções EM TODA PARTE (o que fazemos agora) ou (2) criar classes de fábrica que fazem o que eu disse anteriormente, mas de uma maneira que não faz sentido para iniciantes ou especialistas de Java (o que também fazemos agora). Métodos estáticos não implementados resolvem isso.Agora, vendo as respostas acima, todos sabem que não podemos substituir métodos estáticos, mas não devemos entender mal o conceito de acessar métodos estáticos da subclasse .
Por exemplo, veja o código abaixo: -
Resultado:-
obrigado
fonte
O código a seguir mostra que é possível:
fonte
osm
é .OverridenStaticMeth
OverrideStaticMeth