Я не уверен, что вы хотели бы сделать с абстрактным статическим методом в java, но единственный потенциальный вариант использования, который я видел, описан в прошлом (хотелось бы, чтобы я вспомнил, кем ...) вызывает метод непосредственно для параметра универсального типа.
т.е. если бы ява позволила что-то подобное ...
// 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";}
}
... мы могли бы использовать его для универсального параметра, чтобы вызвать Foo () непосредственно для типа
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
}
Это будет иметь больше смысла в C #, потому что:
- Reified generics означает, что тип не стирается
- в C # операторы являются статическими методами, и вы можете определять свои собственные операторы
В основном это означает, что в «притворном C #» со статическими интерфейсами вы можете использовать что-то, соответствующее приведенному выше коду «притворяться в Java», для написания универсального метода, который работает с любым типом, который определяет конкретный оператор (например, со всем, что имеет оператор "+").
Теперь вернемся к скале. Как scala учитывает этот сценарий?
Отчасти это не так. В Scala нет статических методов: объект - это одиночный объект (т. Е. Класс только с одним экземпляром), но он по-прежнему является классом с обычными методами экземпляра, т. Е. Для объектов, которые все еще вызывают методы только для одного экземпляра, а не непосредственно для типа ( четные операторы являются методами в scala).
Итак, в scala мы написали бы:
trait Foo { def Foo:String }
object FooImpl extends Foo { def Foo = "foo" }
def Test(f: Foo) = f.Foo
... и вызвать наш метод с
scala> Test(FooImpl)
res0: String = foo
// note that FooImpl is still an instance (the only one) of FooImpl and not
// the type itself
Вы можете сделать некоторые трюки с последствиями, чтобы избежать передачи единственного экземпляра в качестве параметра:
implicit def aFoo = FooImpl
def Test2(implicit f: Foo) = f.Foo
теперь это работает:
scala> Test2
res1: String = foo
С более продвинутыми приемами с последствиями, scala также определяет Numeric, что позволяет вам использовать операторы для любого числового значения , даже если они не реализуют общий интерфейс из коробки.