I've read this relevant post, but there weren't many concrete answers (poor language design more or less): Why can't static methods be abstract in Java
I'm a bit of a newcomer to Scala, is this possible in it (maybe with traits or something)?
I tried having my base class extend a trait, but then child classes are required to implement the abstract static method as a member method, when I really want them to be required to be implemented in the companion object.
There aren't static methods in Scala [*], so your question is moot.
However, you can get what you want by extending an object with a trait:
scala> trait A { def foo(): Int }
defined trait A
scala> object C extends A { def foo(): Int = 5 }
defined module C
scala> C.foo
res0: Int = 5
which probably does what you want. There isn't really any way to force something to be implemented in the companion object of a class. The companion object might not exist.
[*] Technically, there are, but this is more of an implementation detail than an overall philosophy. See Method in companion object compiled into static methods in scala?
I'm not sure what you would like to do with an abstract static method in java, but the only potential use case I've seen described in the past (I wish I remembered by whom...) is calling a method directly on a generic type parameter.
i.e. if java allowed something like this...
// 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";}
}
...we could use it on a generic parameter, to call Foo() directly on the type
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
}
This would make somewhat more sense in C# because:
Basically this means in a "pretend C#" with static interfaces, you could use something corresponding to the above "pretend java" code to write a generic method that works on any type that defines a specific operator (e.g. everything that has a "+" operator).
Now, back to scala. How does scala address this scenario? In part it doesn't. Scala has no static methods: an object is a singleton (i.e. a class with only one instance) but still a class with normal, instance methods, i.e. on objects you're still calling methods on the only instance, not directly on the type (even operators are methods in scala).
So in scala we would write:
trait Foo { def Foo:String }
object FooImpl extends Foo { def Foo = "foo" }
def Test(f: Foo) = f.Foo
...and call our method with
scala> Test(FooImpl)
res0: String = foo
// note that FooImpl is still an instance (the only one) of FooImpl and not
// the type itself
You can do some tricks with implicits to avoid passing the only instance as a parameter:
implicit def aFoo = FooImpl
def Test2(implicit f: Foo) = f.Foo
now this works:
scala> Test2
res1: String = foo
With more advanced tricks with implicits, scala also defines Numeric, that allows you to use operators on any numeric value, even though they don't implements a common interface out of the box.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With