摘要静态方法我读过此相关的职位,但并没有很多具体的答案(可怜的语言设计或多或少): Why can't static methods be abstract in Java在斯卡拉
我有点初来乍到斯卡拉的,这是可能的(可能与特质或其他)?
我试图让我的基类扩展一个特征,但是当我真的希望它们被要求在伴随对象中实现时,子类需要实现抽象静态方法作为成员方法。
摘要静态方法我读过此相关的职位,但并没有很多具体的答案(可怜的语言设计或多或少): Why can't static methods be abstract in Java在斯卡拉
我有点初来乍到斯卡拉的,这是可能的(可能与特质或其他)?
我试图让我的基类扩展一个特征,但是当我真的希望它们被要求在伴随对象中实现时,子类需要实现抽象静态方法作为成员方法。
斯卡拉[*]中没有静态方法,所以你的问题是没有意义的。
但是,你可以得到你想要的东西通过与性状扩展的对象:
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
这可能你想要做什么。没有任何办法可以迫使某个类在同伴对象中实现。伴随对象可能不存在。
[*]从技术上讲,这是一个实现细节,而不是整体理念。请参阅Method in companion object compiled into static methods in scala?
实际上,comanion对象的方法可以看作是类的静态方法。 – Nicolas 2012-03-21 10:58:45
@Nicolas是的,在这个类中有一个静态转发器,但正如我所说的,这更像是一个实现细节,以帮助与Java互操作。Scala语言本身没有静态方法的概念。它更像是一个单身人士。 – 2012-03-21 11:52:13
陪伴对象不存在的可能性如何?在编译期间不应该这样做吗? – 2012-03-21 22:58:02
有两种可能的解释为什么抽象静态方法在Scala,Java,C++或C#中是不可能的。
首先是技术性的:抽象/虚拟方法需要引用一个对象(称为这个)来选择一个将要运行的覆盖。当你调用一个静态方法时,你不提供这样的对象。
其次是逻辑:抽象/虚拟静态方法没有任何意义。当你调用一个静态方法时,你总是知道包含该方法的类型。你写:
MyClass.DoSomething(args)
如果你有一个扩展MyClass的MyDerivative,你可以定义另一个静态方法:
MyDerivative.DoSomethingDifferent(args)
有静态虚拟方法只是没有意义的,因为他们的工作只是作为普通的静态方法。
通过“抽象静态方法”,人们通常意味着必须由任何具体子类静态实现的方法。虽然我同意它的形状不好,但它们存在的论点是有效的。例如,请参阅scala集合如何尝试使用“stndard methods”强制创建伴随对象。 – Nicolas 2012-03-21 11:02:30
我不确定你想用java中的抽象静态方法做什么,但是我曾经见过的唯一潜在的用例(我希望我记得谁......)一个直接在泛型类型参数上的方法。
即如果允许的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#中,因为:
基本上这意味着在“假装C#”与静态接口,你可以使用somethi ng对应于上面的“假装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
你可以做一些技巧与implicits避免将唯一的实例作为参数:
implicit def aFoo = FooImpl
def Test2(implicit f: Foo) = f.Foo
现在这个工程:
scala> Test2
res1: String = foo
使用带有隐含的更高级技巧,scala还定义了Numeric,即allows you to use operators on any numeric value,尽管它们并未实现开箱即用的通用接口。
你能告诉我们更多关于你的具体情况吗?为什么你需要将该方法放在伴侣对象中?在scala中可能有不同的方式。 – 2012-03-21 13:48:33
下面是一个例子: 我的基本抽象类有一个抽象的自动更正方法,这不需要绑定到特定的实例。我正在考虑在基本抽象类中使用此自动更正方法的方法。如果该功能不需要在子类中重写,那么我的子类将需要实现自己的自动更正方法 - 因此抽象静态方法。 – 2012-03-21 22:55:39
如果您所做的只是调用未绑定到特定实例的方法,则将该方法放在伴随对象中,然后从您的类和所有子类中调用它。这将是在Scala中正常使用它的方法。 – 2012-03-21 23:13:48