【问题标题】:objects of same class have different methods signature同一类的对象具有不同的方法签名
【发布时间】:2014-10-30 10:22:23
【问题描述】:

看下面的sn-p:

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 之间没有太大区别。 (纠正我,如果我错了),所以我很惊讶地看到 sn-p 是健全的 scala 代码。

那为什么?

【问题讨论】:

    标签: scala anonymous-class


    【解决方案1】:

    您正在使用特征扩展 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();
    }
    

    【讨论】:

    • 感谢 Marth,顺便说一下,在 scala repl 中,我使用了 :type c1 和 :type c2,结果没有给我任何迹象表明这里涉及到 trait。
    • 匿名类不构成(外部可见)类型的一部分。
    【解决方案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 只是允许您使用更简单的语法来完成它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-17
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      相关资源
      最近更新 更多