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

问题描述 投票:1回答:2

请看以下代码段:

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代码。

那为什么呢?

scala anonymous-class
2个回答
6
投票

您要用特征扩展C,所以c1c2是匿名类:

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

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

查看Java代码,您会看到(O是一个周围的对象,可以对其进行编译):

public final class O$$anon$1 extends O$C {
  public java.lang.String m1();
  public O$$anon$1();
}

public final class O$$anon$2 extends O$C {
  public java.lang.String m2();
  public O$$anon$2();
}

1
投票

Java等价于

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

C c2 = new C { 
    public String m2() { ... }
}

现在,您不能直接调用c1.m1(),但可以使用反射来进行操作:

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

Scala仅允许您使用更简单的语法来完成它。

© www.soinside.com 2019 - 2024. All rights reserved.