A questão está em Java, por que não consigo definir um método estático abstrato? por exemplo
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
java
abstract-class
static-methods
hhafez
fonte
fonte
Respostas:
Como "abstrato" significa: "Não implementa funcionalidade" e "estático" significa: "Existe funcionalidade mesmo que você não tenha uma instância de objeto". E isso é uma contradição lógica.
fonte
abstract static
faria todo o sentido. Seria um método do próprio objeto de classe que os objetos da subclasse devem implementar. Obviamente, a maneira como as coisas estão de acordo com a sua resposta está correta, apesar de eu ter me preocupado com o idioma.abstract static
: Uma função X que é "implementada na subclasse" não pode ao mesmo tempo ser "executada na classe" - apenas na subclasse . Onde então não é mais abstrato.static
não significa "não vazio" - isso é apenas uma consequência do Java não permitir que métodos estáticos sejam abstratos. Significa "callable na classe". (Deveria significar "que pode ser chamado apenas na classe", mas isso é outro problema.) Se o Java suportasseabstract static
métodos, eu esperaria que isso significasse que o método 1) deve ser implementado pelas subclasses e 2) é um método de classe da subclasse. Alguns métodos simplesmente não fazem sentido como métodos de instância. Infelizmente, o Java não permite que você especifique isso ao criar uma classe base abstrata (ou uma interface).Design de linguagem ruim. Seria muito mais eficaz chamar diretamente um método abstrato estático do que criar uma instância apenas para usar esse método abstrato. Especialmente verdadeiro ao usar uma classe abstrata como uma solução alternativa para a incapacidade de extensão, que é outro exemplo ruim de design. Espero que eles resolvam essas limitações em um próximo lançamento.
fonte
static
si já é uma violação ....Você não pode substituir um método estático, tornando-o abstrato não faria sentido. Além disso, um método estático em uma classe abstrata pertenceria a essa classe, e não a classe de substituição, portanto não poderia ser usado de qualquer maneira.
fonte
A
abstract
anotação para um método indica que o método DEVE ser substituído em uma subclasse.Em Java, um
static
membro (método ou campo) não pode ser substituído por subclasses (isso não é necessariamente verdadeiro em outras linguagens orientadas a objetos, consulte SmallTalk.) Umstatic
membro pode estar oculto , mas isso é fundamentalmente diferente de substituído .Como os membros estáticos não podem ser substituídos em uma subclasse, a
abstract
anotação não pode ser aplicada a eles.Como um aparte - outras linguagens suportam herança estática, assim como herança de instância. De uma perspectiva de sintaxe, esses idiomas geralmente exigem que o nome da classe seja incluído na declaração. Por exemplo, em Java, supondo que você esteja escrevendo código na ClassA, estas são instruções equivalentes (se methodA () for um método estático e não houver um método de instância com a mesma assinatura):
e
No SmallTalk, o nome da classe não é opcional; portanto, a sintaxe é (observe que o SmallTalk não usa o.
Como o nome da classe sempre é obrigatório, a "versão" correta do método sempre pode ser determinada percorrendo a hierarquia da classe. Pelo que vale, às vezes sinto falta da
static
herança e fui mordido pela falta de herança estática no Java quando comecei com ela. Além disso, o SmallTalk é do tipo pato (e, portanto, não oferece suporte a programa por contrato.) Portanto, ele não possuiabstract
modificadores para os membros da classe.fonte
Eu também fiz a mesma pergunta, aqui está o porquê
Como a classe Abstract diz, ela não dará implementação e permitirá que a subclasse dê
então a subclasse precisa substituir os métodos da superclasse,
REGRA Nº 1 - Um método estático não pode ser substituído
Como membros e métodos estáticos são elementos de tempo de compilação, é por isso que Sobrecarga (Polimorfismo em tempo de compilação) de métodos estáticos é permitida, em vez de Substituir (Polimorfismo em tempo de execução)
Então, eles não podem ser abstratos.
Não existe algo como estática abstrata <--- Não é permitido no Universo Java
fonte
abstract static
consulte stackoverflow.com/questions/370962/… . A verdadeira razão pela qual o Java não permite que os métodos estáticos sejam substituídos é porque o Java não permite que os métodos estáticos sejam substituídos.foo(String)
não é o mesmo quefoo(Integer)
- isso é tudo.Este é um design de linguagem terrível e realmente não há razão para que isso não seja possível.
De fato, aqui está uma implementação de como PODE ser feito em JAVA :
================= Exemplo antigo abaixo =================
Procure getRequest e getRequestImpl ... setInstance pode ser chamado para alterar a implementação antes que a chamada seja feita.
Usado como segue:
fonte
abstract static
método, conforme solicitado na pergunta, e escreveu em negrito PODE SER FEITO EM JAVA . Isso é completamente errado.Um método abstrato é definido apenas para que possa ser substituído em uma subclasse. No entanto, métodos estáticos não podem ser substituídos. Portanto, é um erro em tempo de compilação ter um método estático abstrato.
Agora, a próxima pergunta é por que métodos estáticos não podem ser substituídos?
É porque os métodos estáticos pertencem a uma classe específica e não a sua instância. Se você tentar substituir um método estático, não receberá nenhum erro de compilação ou tempo de execução, mas o compilador apenas ocultará o método estático da superclasse.
fonte
Um método estático, por definição, não precisa saber
this
. Portanto, não pode ser um método virtual (sobrecarregado de acordo com as informações da subclasse dinâmica disponíveis por meio dethis
); em vez disso, uma sobrecarga de método estático é baseada exclusivamente nas informações disponíveis no tempo de compilação (isto significa: depois de consultar um método estático de superclasse, você chama o método de superclasse, mas nunca um método de subclasse).De acordo com isso, métodos estáticos abstratos seriam bastante inúteis porque você nunca terá sua referência substituída por algum corpo definido.
fonte
Vejo que já existem um zilhão de respostas, mas não vejo soluções práticas. É claro que esse é um problema real e não há boas razões para excluir essa sintaxe em Java. Como a pergunta original não possui um contexto em que isso possa ser necessário, forneço um contexto e uma solução:
Suponha que você tenha um método estático em várias classes idênticas. Esses métodos chamam um método estático específico da classe:
doWork()
métodosC1
eC2
são idênticos. Pode haver muitas dessas calsses:C3
C4
etc. Sestatic abstract
fosse permitido, você eliminaria o código duplicado fazendo algo como:mas isso não seria compilado porque a
static abstract
combinação não é permitida. No entanto, isso pode ser contornado com astatic class
construção, que é permitida:Com esta solução, o único código duplicado é
fonte
C1.doWork()
ouC2.doWork()
Mas você não pode ligarC.doWork()
. Também no exemplo que você forneceu, que não funcionará, suponha que se fosse permitido, então como a classeC
encontrará a implementação dedoMoreWork()
? Finalmente, eu chamaria seu código de contexto de um design ruim. Por quê? simplesmente porque você criou uma função separada para o código exclusivo, em vez de criar uma função comum para o código e implementar uma função estática na classeC
. Isso é mais fácil !!!Suponha que há duas classes
Parent
eChild
.Parent
éabstract
. As declarações são as seguintes:Isso significa que qualquer instância de
Parent
deve especificar comorun()
é executada.No entanto, assuma agora que
Parent
não éabstract
.Isso significa que
Parent.run()
irá executar o método estático.A definição de um
abstract
método é "Um método declarado, mas não implementado", o que significa que ele não retorna nada.A definição de um
static
método é "Um método que retorna o mesmo valor para os mesmos parâmetros, independentemente da instância na qual é chamado".O
abstract
valor de retorno de um método será alterado conforme a instância. Umstatic
método não. Umstatic abstract
método é basicamente um método em que o valor de retorno é constante, mas não retorna nada. Isso é uma contradição lógica.Além disso, não há realmente um motivo para um
static abstract
método.fonte
Uma classe abstrata não pode ter um método estático porque a abstração é feita para obter DYNAMIC BINDING enquanto os métodos estáticos estão estaticamente ligados à sua funcionalidade.Um método estático significa comportamento não dependente de uma variável de instância, portanto, nenhuma instância / objeto é necessário. Os métodos estáticos pertencem à classe e não ao objeto. Eles são armazenados em uma área de memória conhecida como PERMGEN, de onde é compartilhada com todos os objetos. Métodos na classe abstrata são ligados dinamicamente à sua funcionalidade.
fonte
Declarar um método como
static
meio, podemos chamá-lo por seu nome de classe e, se essa classeabstract
também for, não faz sentido chamá-lo, pois ele não contém nenhum corpo e, portanto, não podemos declarar um método comostatic
eabstract
.fonte
Como os métodos abstratos pertencem à classe e não podem ser substituídos pela classe de implementação. Mesmo se houver um método estático com a mesma assinatura, ele oculta o método, não o substitui. Portanto, é irrelevante declarar o método abstrato tão estático quanto nunca obterá o corpo. Assim, compile o erro de tempo.
fonte
Um método estático pode ser chamado sem uma instância da classe. No seu exemplo, você pode chamar foo.bar2 (), mas não foo.bar (), porque para bar você precisa de uma instância. O código a seguir funcionaria:
Se você chamar um método estático, ele será executado sempre com o mesmo código. No exemplo acima, mesmo se você redefinir bar2 no ImplementsFoo, uma chamada para var.bar2 () executaria foo.bar2 ().
Se bar2 agora não tem implementação (é isso que significa abstrato), você pode chamar um método sem implementação. Isso é muito prejudicial.
fonte
Acredito que encontrei a resposta para essa pergunta, na forma de por que os métodos de uma interface (que funcionam como métodos abstratos em uma classe pai) não podem ser estáticos. Aqui está a resposta completa (não a minha)
Métodos basicamente estáticos podem ser vinculados em tempo de compilação, pois para chamá-los, você precisa especificar uma classe. Isso é diferente dos métodos de instância, para os quais a classe da referência da qual você está chamando o método pode ser desconhecida no momento da compilação (portanto, qual bloco de código é chamado pode ser determinado apenas em tempo de execução).
Se você está chamando um método estático, já conhece a classe em que é implementado ou qualquer subclasse direta dele. Se você definir
Qualquer
Foo.bar();
ligação é obviamente ilegal e você sempre usaráFoo2.bar();
.Com isso em mente, o único objetivo de um método abstrato estático seria impor subclasses para implementar esse método. Você pode inicialmente achar que isso é MUITO errado, mas se você tiver um parâmetro de tipo genérico
<E extends MySuperClass>
, seria bom garantir via interfaceE
possível.doSomething()
. Lembre-se de que, devido ao tipo de apagamento, os genéricos existem apenas no momento da compilação.Então, seria útil? Sim, e talvez seja por isso que o Java 8 esteja permitindo métodos estáticos nas interfaces (embora apenas com uma implementação padrão). Por que não abstrair métodos estáticos com uma implementação padrão nas classes? Simplesmente porque um método abstrato com uma implementação padrão é realmente um método concreto.
Por que não abstrair / métodos estáticos de interface sem implementação padrão? Aparentemente, apenas por causa da maneira como o Java identifica qual bloco de código ele deve executar (primeira parte da minha resposta).
fonte
Como classe abstrata é um conceito OOPS e membros estáticos não fazem parte do OOPS ....
Agora, podemos declarar métodos estáticos completos na interface e podemos executar a interface declarando o método principal dentro de uma interface
fonte
A idéia de ter um método estático abstrato seria que você não pode usar essa classe abstrata específica diretamente para esse método, mas somente a primeira derivada poderá implementar esse método estático (ou para genéricos: a classe real do genérico você usar).
Dessa forma, você pode criar, por exemplo, uma classe abstrata sortableObject ou até mesmo fazer interface com métodos estáticos (auto-) abstratos, que definem os parâmetros das opções de classificação:
Agora você pode definir um objeto classificável que pode ser classificado pelos principais tipos que são iguais para todos esses objetos:
Agora você pode criar um
que pode recuperar os tipos, criar um menu pop-up para selecionar um tipo para classificar e recorrer à lista, obtendo os dados desse tipo, bem como criar uma função de adição que, quando um tipo de classificação foi selecionado, pode ser ativada automaticamente -sorte novos itens. Observe que a instância de SortableList pode acessar diretamente o método estático de "T":
O problema de ter que usar uma instância é que o SortableList pode ainda não ter itens, mas já precisa fornecer a classificação preferida.
Cheerio, Olaf.
fonte
Primeiro, um ponto chave sobre as classes abstratas - Uma classe abstrata não pode ser instanciada (consulte o wiki ). Portanto, você não pode criar nenhuma instância de uma classe abstrata.
Agora, a maneira como o java lida com métodos estáticos é compartilhando o método com todas as instâncias dessa classe.
Portanto, se você não pode instanciar uma classe, essa classe não pode ter métodos estáticos abstratos, pois um método abstrato implora para ser estendido.
Estrondo.
fonte
Conforme o documento Java :
No Java 8, junto com os métodos padrão, os métodos estáticos também são permitidos em uma interface. Isso facilita a organização de métodos auxiliares em nossas bibliotecas. Podemos manter métodos estáticos específicos para uma interface na mesma interface, em vez de em uma classe separada.
Um bom exemplo disso é:
ao invés de
Outro exemplo de uso de métodos estáticos também é fornecido no próprio documento :
fonte
Como 'abstrato' significa que o método deve ser substituído e não se pode substituir os métodos 'estáticos'.
fonte
Os métodos regulares podem ser abstratos quando devem ser substituídos por subclasses e fornecidos com funcionalidade. Imagine que a classe
Foo
é estendida porBar1, Bar2, Bar3
etc. Portanto, cada um terá sua própria versão da classe abstrata de acordo com suas necessidades.Agora, os métodos estáticos por definição pertencem à classe, eles não têm nada a ver com os objetos da classe ou os objetos de suas subclasses. Eles nem precisam que eles existam, eles podem ser usados sem instanciar as classes. Portanto, eles precisam estar prontos para uso e não podem depender das subclasses para adicionar funcionalidade a eles.
fonte
Como abstract é uma palavra-chave aplicada sobre métodos Abstract, não especifica um corpo. E se falamos de palavra-chave estática, ela pertence à área de classe.
fonte
porque se você estiver usando algum membro estático ou variável estática na classe, ele será carregado no momento do carregamento da classe.
fonte
Você pode fazer isso com interfaces no Java 8.
Esta é a documentação oficial sobre o assunto:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
fonte
Porque se uma classe estende uma classe abstrata, ela deve substituir os métodos abstratos, e isso é obrigatório. E como os métodos estáticos são métodos de classe resolvidos em tempo de compilação, enquanto os métodos substituídos são métodos de instância resolvidos em tempo de execução e após o polimorfismo dinâmico.
fonte