Scala 同一类的对象具有不同的签名方法

Scala 同一类的对象具有不同的签名方法,scala,anonymous-class,Scala,Anonymous Class,请看以下代码段: class C val c1 = new C { def m1 = "c1 has m1" } val c2 = new C { def m2 = "c2 has m2" } c1.m1 c2.m2 //c2.m1 //c1.m2 在REPL中运行它,那么你就知道我的意思了 我有限的java知识告诉我,在java中,同一类的对象将具有相同的方法符号,而且就OO而言,java和scala之间没有太大区别。如果我错了,请纠正我的错误,因此我非常惊讶地看到这个片段是健全的scal

请看以下代码段:

class C
val c1 = new C { def m1 = "c1 has m1" }
val c2 = new C { def m2 = "c2 has m2" }

c1.m1
c2.m2
//c2.m1
//c1.m2
在REPL中运行它,那么你就知道我的意思了

我有限的java知识告诉我,在java中,同一类的对象将具有相同的方法符号,而且就OO而言,java和scala之间没有太大区别。如果我错了,请纠正我的错误,因此我非常惊讶地看到这个片段是健全的scala代码

那为什么呢?

你在用traits扩展C,所以c1和c2是匿名类:

scala> c1.getClass
res0: java.lang.Class[_ <: C] = class $anon$1

scala> c2.getClass
res1: java.lang.Class[_ <: C] = class $anon$2
您使用traits扩展了C,因此c1和c2是匿名类:

scala> c1.getClass
res0: java.lang.Class[_ <: C] = class $anon$1

scala> c2.getClass
res1: java.lang.Class[_ <: C] = class $anon$2
Java等价物是

C c1 = new C { 
    public String m1() { ... }
}

C c2 = new C { 
    public String m2() { ... }
}
现在,您不能直接调用c1.m1,但可以使用反射:

c1.getClass().getMethod("m1").invoke(c1)
Scala只允许您使用更简单的语法来实现这一点。

Java等价物是

C c1 = new C { 
    public String m1() { ... }
}

C c2 = new C { 
    public String m2() { ... }
}
现在,您不能直接调用c1.m1,但可以使用反射:

c1.getClass().getMethod("m1").invoke(c1)

Scala只允许您使用一种更简单的语法。

谢谢Marth,顺便说一句,在Scala repl中,我使用:type c1和:type c2,结果没有告诉我这里涉及到trait。匿名类不构成外部可见类型的一部分。谢谢Marth,顺便说一句,在Scala repl中,我使用:type c1和:type c2,结果没有给我任何迹象表明这里涉及trait。匿名类不构成外部可见类型的一部分。