La pregunta es en Java ¿por qué no puedo definir un método estático abstracto? por ejemplo
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
java
abstract-class
static-methods
hhafez
fuente
fuente
Respuestas:
Porque "abstracto" significa: "No implementa ninguna funcionalidad", y "estático" significa: "Hay funcionalidad incluso si no tiene una instancia de objeto". Y eso es una contradicción lógica.
fuente
abstract static
tendría mucho sentido. Sería un método del propio objeto de clase que los objetos de subclase deben implementar. Por supuesto, la forma en que las cosas resuelven su respuesta es correcta a pesar de mi comprensión del idioma.abstract static
: Una función X que está "implementada en la subclase" no puede al mismo tiempo "ejecutarse en la clase", solo en la subclase . Donde entonces ya no es abstracto.static
no significa "no vacío", eso es solo una consecuencia de que Java no permite que los métodos estáticos sean abstractos. Significa "invocable en la clase". (Debería significar "invocable solo en la clase", pero ese es otro problema). Si Java admiteabstract static
métodos, esperaría que signifique que el método 1) debe ser implementado por subclases, y 2) es un método de clase de la subclase. Algunos métodos simplemente no tienen sentido como métodos de instancia. Desafortunadamente, Java no le permite especificar eso al crear una clase base abstracta (o una interfaz).Mal diseño del lenguaje. Sería mucho más efectivo llamar directamente a un método abstracto estático que crear una instancia solo por usar ese método abstracto. Especialmente cierto cuando se utiliza una clase abstracta como solución alternativa para la incapacidad de enumeración, que es otro mal ejemplo de diseño. Espero que resuelvan esas limitaciones en un próximo lanzamiento.
fuente
static
sí mismo ya es una violación ...No puede anular un método estático, por lo que hacerlo abstracto no tendría sentido. Además, un método estático en una clase abstracta pertenecería a esa clase, y no a la clase superior, por lo que no podría usarse de todos modos.
fuente
La
abstract
anotación a un método indica que el método DEBE ser anulado en una subclase.En Java, un
static
miembro (método o campo) no puede ser anulado por subclases (esto no es necesariamente cierto en otros lenguajes orientados a objetos, vea SmallTalk). Unstatic
miembro puede estar oculto , pero eso es fundamentalmente diferente de anulado .Dado que los miembros estáticos no se pueden reemplazar en una subclase, la
abstract
anotación no se puede aplicar a ellos.Por otro lado, otros lenguajes admiten herencia estática, al igual que la herencia de instancia. Desde una perspectiva de sintaxis, esos idiomas generalmente requieren que se incluya el nombre de la clase en la declaración. Por ejemplo, en Java, suponiendo que está escribiendo código en la Clase A, estas son declaraciones equivalentes (si el método A () es un método estático y no hay un método de instancia con la misma firma):
y
En SmallTalk, el nombre de la clase no es opcional, por lo que la sintaxis es (tenga en cuenta que SmallTalk no usa. Para separar el "sujeto" y el "verbo", sino que lo usa como el terminador de enmienda de estado):
Debido a que siempre se requiere el nombre de la clase, la "versión" correcta del método siempre se puede determinar atravesando la jerarquía de la clase. Por lo que vale, ocasionalmente extraño la
static
herencia, y me mordió la falta de herencia estática en Java cuando comencé con ella. Además, SmallTalk es de tipo pato (y, por lo tanto, no es compatible con el programa por contrato). Por lo tanto, no tiene unabstract
modificador para los miembros de la clase.fuente
También hice la misma pregunta, aquí es por qué
Como dice la clase Abstract, no dará implementación y permitirá que la subclase le dé
entonces la subclase tiene que anular los métodos de la superclase,
REGLA NO 1 - Un método estático no puede ser anulado
Debido a que los miembros y métodos estáticos son elementos de tiempo de compilación, es por eso que se permite la sobrecarga (polimorfismo en tiempo de compilación) de métodos estáticos en lugar de anulación (polimorfismo de tiempo de ejecución)
Por lo tanto, no pueden ser abstractos.
No hay nada como abstracto estático <--- No permitido en Java Universe
fuente
abstract static
ver stackoverflow.com/questions/370962/… . La verdadera razón por la que Java no permite que se anulen los métodos estáticos es porque Java no permite que se anulen los métodos estáticos.foo(String)
que no es lo mismo quefoo(Integer)
eso es todo.Este es un diseño de lenguaje terrible y realmente no hay razón de por qué no puede ser posible.
De hecho, aquí hay una implementación sobre cómo PUEDE hacerse en JAVA :
================= Viejo ejemplo a continuación =================
Busque getRequest y getRequestImpl ... se puede llamar a setInstance para alterar la implementación antes de realizar la llamada.
Utilizado de la siguiente manera:
fuente
abstract static
método como se le preguntó en la pregunta y ha escrito en negrita SE PUEDE HACER EN JAVA . Esto es completamente equivocado.Un método abstracto se define solo para que pueda ser anulado en una subclase. Sin embargo, los métodos estáticos no se pueden anular. Por lo tanto, es un error en tiempo de compilación tener un método abstracto y estático.
Ahora la siguiente pregunta es ¿por qué los métodos estáticos no se pueden anular?
Es porque los métodos estáticos pertenecen a una clase particular y no a su instancia. Si intenta anular un método estático, no obtendrá ningún error de compilación o tiempo de ejecución, pero el compilador simplemente ocultará el método estático de la superclase.
fuente
Un método estático, por definición, no necesita saberlo
this
. Por lo tanto, no puede ser un método virtual (que se sobrecarga de acuerdo con la información de subclase dinámica disponible a través dethis
); en cambio, la sobrecarga de un método estático se basa únicamente en la información disponible en el momento de la compilación (esto significa: una vez que hace referencia a un método estático de superclase, llama al método de superclase, pero nunca a un método de subclase).De acuerdo con esto, los métodos estáticos abstractos serían bastante inútiles porque nunca se sustituirá su referencia por algún cuerpo definido.
fuente
Veo que ya hay un millón de respuestas, pero no veo ninguna solución práctica. Por supuesto, este es un problema real y no hay una buena razón para excluir esta sintaxis en Java. Como la pregunta original carece de un contexto en el que esto pueda ser necesario, proporciono tanto un contexto como una solución:
Suponga que tiene un método estático en un grupo de clases que son idénticas. Estos métodos llaman a un método estático que es específico de la clase:
doWork()
Los métodosC1
yC2
son idénticos. Puede haber muchas de estas clases:C3
C4
etc. Sistatic abstract
se permitiera, eliminaría el código duplicado haciendo algo como:pero esto no se compilaría porque la
static abstract
combinación no está permitida. Sin embargo, esto se puede evitar con lastatic class
construcción, que está permitida:Con esta solución, el único código que se duplica es
fuente
C1.doWork()
oC2.doWork()
Pero no puede llamarC.doWork()
. También en el ejemplo que ha proporcionado, que no funcionará, suponga que si estuviera permitido, ¿cómoC
encontrará la implementación la clasedoMoreWork()
? Finalmente, llamaría a su código de contexto un mal diseño. ¿Por qué? simplemente porque ha creado una función separada para el código que es única en lugar de crear una función para el código que es común y luego implementar una función estática en la claseC
. ¡Esto es más fácil!Suponga que hay dos clases,
Parent
yChild
.Parent
esabstract
. Las declaraciones son las siguientes:Esto significa que cualquier instancia de
Parent
debe especificar cómorun()
se ejecuta.Sin embargo, suponga que ahora
Parent
no lo esabstract
.Esto significa que
Parent.run()
ejecutará el método estático.La definición de un
abstract
método es "Un método que se declara pero no se implementa", lo que significa que no devuelve nada por sí mismo.La definición de un
static
método es "Un método que devuelve el mismo valor para los mismos parámetros, independientemente de la instancia en la que se llame".El
abstract
valor de retorno de un método cambiará a medida que cambie la instancia. Unstatic
método no lo hará. Unstatic abstract
método es más o menos un método donde el valor de retorno es constante, pero no devuelve nada. Esta es una contradicción lógica.Además, realmente no hay muchas razones para un
static abstract
método.fuente
Una clase abstracta no puede tener un método estático porque la abstracción se realiza para lograr la VINCULACIÓN DINÁMICA mientras que los métodos estáticos están vinculados estáticamente a su funcionalidad. Un método estático significa comportamiento que no depende de una variable de instancia, por lo que no se requiere instancia / objeto. Solo la clase. Los métodos estáticos pertenecen a la clase y no al objeto. Se almacenan en un área de memoria conocida como PERMGEN desde donde se comparte con cada objeto. Los métodos en la clase abstracta están vinculados dinámicamente a su funcionalidad.
fuente
Declarar un método como
static
significa que podemos llamar a ese método por su nombre de clase y si esa clase también lo esabstract
, no tiene sentido llamarlo ya que no contiene ningún cuerpo, y por lo tanto no podemos declarar un método comostatic
yabstract
.fuente
Como los métodos abstractos pertenecen a la clase y no pueden ser anulados por la clase implementadora. Incluso si hay un método estático con la misma firma, oculta el método, no lo anula. Por lo tanto, es irrelevante declarar el método abstracto como estático, ya que nunca obtendrá el cuerpo. Por lo tanto, error de tiempo de compilación.
fuente
Se puede llamar a un método estático sin una instancia de la clase. En su ejemplo, puede llamar a foo.bar2 (), pero no a foo.bar (), porque para la barra necesita una instancia. El siguiente código funcionaría:
Si llama a un método estático, se ejecutará siempre el mismo código. En el ejemplo anterior, incluso si redefine bar2 en ImplementsFoo, una llamada a var.bar2 () ejecutaría foo.bar2 ().
Si bar2 ahora no tiene implementación (eso es lo que significa abstracto), puede llamar a un método sin implementación. Eso es muy dañino.
fuente
Creo que he encontrado la respuesta a esta pregunta, en forma de por qué los métodos de una interfaz (que funcionan como métodos abstractos en una clase principal) no pueden ser estáticos. Aquí está la respuesta completa (no la mía)
Básicamente, los métodos estáticos pueden vincularse en tiempo de compilación, ya que para llamarlos debe especificar una clase. Esto es diferente a los métodos de instancia, para los cuales la clase de la referencia desde la que está llamando al método puede ser desconocida en el momento de la compilación (por lo tanto, qué bloque de código se llama solo se puede determinar en tiempo de ejecución).
Si está llamando a un método estático, ya conoce la clase donde se implementa, o cualquier subclase directa de la misma. Si usted define
Entonces, cualquier
Foo.bar();
llamada es obviamente ilegal, y siempre la usaráFoo2.bar();
.Con esto en mente, el único propósito de un método abstracto estático sería imponer subclases para implementar dicho método. Inicialmente, podría pensar que esto es MUY incorrecto, pero si tiene un parámetro de tipo genérico
<E extends MySuperClass>
, sería bueno garantizarlo a través de la interfaz queE
puede.doSomething()
. Tenga en cuenta que debido al tipo de borrado, los genéricos solo existen en el momento de la compilación.Entonces, ¿sería útil? Sí, y tal vez por eso Java 8 permite métodos estáticos en las interfaces (aunque solo con una implementación predeterminada). ¿Por qué no abstraer métodos estáticos con una implementación predeterminada en las clases? Simplemente porque un método abstracto con una implementación predeterminada es en realidad un método concreto.
¿Por qué no los métodos estáticos abstractos / de interfaz sin implementación predeterminada? Aparentemente, simplemente por la forma en que Java identifica qué bloque de código tiene que ejecutar (primera parte de mi respuesta).
fuente
Debido a que la clase abstracta es un concepto OOPS y los miembros estáticos no son parte de OOPS ...
Ahora, podemos declarar métodos completos estáticos en la interfaz y podemos ejecutar la interfaz declarando el método principal dentro de una interfaz
fuente
La idea de tener un método estático abstracto sería que no puede usar esa clase abstracta en particular directamente para ese método, pero solo la primera derivada podría implementar ese método estático (o para genéricos: la clase real del genérico que utilizar).
De esa manera, podría crear, por ejemplo, una clase abstracta de objeto sortable o incluso una interfaz con métodos estáticos (auto) abstractos, que definen los parámetros de las opciones de clasificación:
Ahora puede definir un objeto ordenable que se pueda ordenar por los tipos principales que son iguales para todos estos objetos:
Ahora puedes crear un
que puede recuperar los tipos, crear un menú emergente para seleccionar un tipo para ordenar y recurrir a la lista obteniendo los datos de ese tipo, así como tener una función de agregar que, cuando se ha seleccionado un tipo de clasificación, puede auto -ordenar nuevos elementos. Tenga en cuenta que la instancia de SortableList puede acceder directamente al método estático de "T":
El problema con tener que usar una instancia es que SortableList puede no tener elementos todavía, pero ya necesita proporcionar la clasificación preferida.
Cheerio, Olaf.
fuente
Primero, un punto clave sobre las clases abstractas: una clase abstracta no se puede instanciar (ver wiki ). Por lo tanto, no puede crear ninguna instancia de una clase abstracta.
Ahora, la forma en que java trata los métodos estáticos es compartiendo el método con todas las instancias de esa clase.
Entonces, si no puede crear una instancia de una clase, esa clase no puede tener métodos estáticos abstractos ya que un método abstracto pide que se extienda.
Auge.
fuente
Según el documento de Java :
En Java 8, junto con los métodos predeterminados, también se permiten métodos estáticos en una interfaz. Esto nos facilita la organización de métodos auxiliares en nuestras bibliotecas. Podemos mantener métodos estáticos específicos para una interfaz en la misma interfaz en lugar de en una clase separada.
Un buen ejemplo de esto es:
en vez de
Otro ejemplo de uso de métodos estáticos también se da en el propio documento :
fuente
Porque 'abstracto' significa que el método debe ser anulado y uno no puede anular los métodos 'estáticos'.
fuente
Los métodos regulares pueden ser abstractos cuando están destinados a ser anulados por subclases y provistos de funcionalidad. Imagina que la clase
Foo
se extiende porBar1, Bar2, Bar3
etc. Por lo tanto, cada uno tendrá su propia versión de la clase abstracta de acuerdo con sus necesidades.Ahora, los métodos estáticos, por definición, pertenecen a la clase, no tienen nada que ver con los objetos de la clase o los objetos de sus subclases. Ni siquiera necesitan que existan, se pueden usar sin crear instancias de las clases. Por lo tanto, deben estar listos y no pueden depender de las subclases para agregarles funcionalidad.
fuente
Debido a que abstract es una palabra clave que se aplica sobre los métodos Abstract, no se especifica un cuerpo. Y si hablamos de palabras clave estáticas, pertenece al área de clase.
fuente
porque si está utilizando algún miembro estático o variable estática en la clase, se cargará en el momento de carga de la clase.
fuente
Puede hacer esto con interfaces en Java 8.
Esta es la documentación oficial al respecto:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
fuente
Porque si una clase extiende una clase abstracta, tiene que anular los métodos abstractos y eso es obligatorio. Y dado que los métodos estáticos son métodos de clase resueltos en tiempo de compilación, mientras que los métodos anulados son métodos de instancia resueltos en tiempo de ejecución y siguiendo un polimorfismo dinámico.
fuente