Puede encontrarse en la posición de pensar en hacer un método estático final, considerando lo siguiente:
Tener las siguientes clases:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
Ahora la forma 'correcta' de llamar a estos métodos sería
A.ts();
B.ts();
lo que resultaría en, AB
pero también podría llamar a los métodos en instancias:
A a = new A();
a.ts();
B b = new B();
b.ts();
lo que resultaría AB
también.
Ahora considere lo siguiente:
A a = new B();
a.ts();
eso se imprimiría A
. Eso podría sorprenderlo ya que en realidad está teniendo un objeto de clase B
. Pero como lo está llamando desde una referencia de tipo A
, llamará A.ts()
. Puede imprimir B
con el siguiente código:
A a = new B();
((B)a).ts();
En ambos casos, el objeto que tiene es en realidad de la clase B
. Pero dependiendo del puntero que apunta al objeto, llamará al método desde A
o desde B
.
Ahora digamos que usted es el desarrollador de la clase A
y desea permitir la subclasificación. Pero realmente desea un método ts()
, siempre que se lo llame, incluso desde una subclase, que hace lo que quiere que haga y que no esté oculto por una versión de subclase. Entonces podría hacerlo final
y evitar que se oculte en la subclase. Y puede estar seguro de que el siguiente código llamará al método desde su clase A
:
B b = new B();
b.ts();
Ok, admitidamente, eso está construido de alguna manera, pero podría tener sentido para algunos casos.
No debe llamar a métodos estáticos en instancias sino directamente en las clases, entonces no tendrá ese problema. También IntelliJ IDEA, por ejemplo, le mostrará una advertencia, si llama a un método estático en una instancia y también si hace que un método estático sea final.