No estoy seguro de qué le gustaría hacer con un método estático abstracto en Java, pero el único caso de uso potencial que he visto descrito en el pasado (me gustaría recordar por quién ...) está llamando un método directamente en un parámetro de tipo genérico.
es decir, si Java permitió que algo como esto ...
// this is not valid java...
// let's pretend we can define a static method in an interface
interface Foo {
static String Foo();
}
// a class that implements our interface
class FooImpl implements Foo {
public static String Foo() {return "foo";}
}
...podríamos utilizarlo en un parámetro genérico, para llamar Foo() directamente en el tipo
static <T extends Foo> String Test() {
return T.Foo(); // even if our hypothetical static interface
// was a valid thing, this would probably still fail
// due to type erasure
}
Esto haría un poco más sentido en C# porque:
- genéricos reificadas significan el tipo no se borran
- en los operadores de C# son los métodos estáticos y se puede define your own operators
Básicamente esto significa que en un "pretender C#" con interfaces estáticas, se puede usar somethi ng correspondiente al código "pretender java" anterior para escribir un método genérico que funciona en cualquier tipo que defina un operador específico (p. todo lo que tiene un operador "+").
Ahora, volviendo a scala. ¿Cómo aborda scala este escenario? En parte no es así. Scala no tiene métodos estáticos: un objeto es un singleton (es decir, una clase con solo una instancia) pero sigue siendo una clase con métodos de instancia normales, es decir, en objetos todavía llama métodos en la única instancia, no directamente en el tipo (incluso los operadores son métodos en scala).
Así que en Scala escribiríamos:
trait Foo { def Foo:String }
object FooImpl extends Foo { def Foo = "foo" }
def Test(f: Foo) = f.Foo
... y llamar a nuestro método con
scala> Test(FooImpl)
res0: String = foo
// note that FooImpl is still an instance (the only one) of FooImpl and not
// the type itself
Puede hacer algunos trucos con los implícitos para evitar pasar la única instancia como un parámetro:
implicit def aFoo = FooImpl
def Test2(implicit f: Foo) = f.Foo
ahora esto funciona:
scala> Test2
res1: String = foo
Con más trucos avanzados con implicitos, scala también define Numeric, que allows you to use operators on any numeric value, aunque no implemente una interfaz común de fábrica.
¿Puedes contarnos un poco más sobre tu situación específica? ¿Por qué necesita que el método esté en el objeto complementario? Puede haber una manera diferente de hacerlo en scala. –
Aquí hay un ejemplo: Mi clase abstracta base tiene un método de autocorrección abstracto, esto no necesita estar vinculado a una instancia específica. Estoy considerando implementar métodos en la clase abstracta base que usaría este método de autocorrección. Si no es necesario anular la funcionalidad en las clases secundarias, mis clases secundarias deberán implementar su propio método de autocorrección, por lo tanto, métodos estáticos abstractos. –
Si todo lo que hace es llamar a un método que no está vinculado a una instancia específica, coloque el método en el objeto complementario y llámelo desde su clase y todas las subclases. Esa sería la forma normal de hacerlo en Scala. –