【问题标题】:How to get the concrete class for a mixed in trait如何获得混合特征的具体类
【发布时间】:2020-11-29 05:50:53
【问题描述】:

假设我具有以下特征和类别:

trait A {
    def foo(): Unit
}

trait B extends A {
    abstract override def foo(): Unit = {
        // Can I determine the name of the concrete class here?
        super.foo()
    }
}

class C extends A {
    def foo() = {
        println("C::foo()")
    }
}

val c = new C with B
c.foo()

有没有办法从特征 B 中确定实例化它的具体类的名称?即 C

【问题讨论】:

  • 有没有办法从特征 B 中确定实例化它的具体类的名称?即 C B 未在 C 中实例化。
  • 你的意思是val c = new C with B
  • 好吧,我相信你可以打电话给this.getClass.getName 但是,你为什么想要类名呢?你想用这些信息做什么?
  • 坦率地说,这听起来像是一个坏主意。如果您的 trait 需要了解扩展它们的类,那么您的设计就失败了。
  • 但是在这种情况下,“最终演员”不是 C,它是一个匿名类。

标签: scala inheritance overriding


【解决方案1】:

试试.getClass.getSuperclass.getSimpleName

trait A {
  def foo(): Unit
}

trait B extends A {
  abstract override def foo(): Unit = {
    println("B is instantiated in " + getClass.getSuperclass.getSimpleName)
    super.foo()
  }
}

class C extends A {
  def foo() = {
    println("C::foo()")
  }
}

val c = new C with B
c.foo()
//B is instantiated in C
//C::foo()

【讨论】:

    【解决方案2】:

    让我们稍微修改一下您的代码,因为它无法编译。当从 B 调用 super.foo 时,你会得到一个异常,因为它没有实现。

    package test
    
    object HelloWorld1 {
      trait A {
        def foo(): Unit
      }
    
      trait B extends A {
        override def foo(): Unit = {
          println(getClass.getName)
          // Can I determine the name of the concrete class here?
        }
      }
    
      class C extends B {  }
    
      class D extends B { }
    
      def main(args: Array[String]): Unit = {
        val c = new C
        c.foo()
        val d = new D
        d.foo()
      }
    }
    

    根据该代码,您可以调用 getClass.getName,它会提供一个字符串,由完整的包名和当前的类构成。

    在给定的示例中,您将获得:

    test.HelloWorld1$C
    test.HelloWorld1$D
    

    如果您在 HelloWorld1 之外参加 C 和 D 课程,您将获得:

    C
    D
    

    如果您只想在第一个选项中获得CD,即在HelloWorld1 中,您可以调用getClass.getSimpleName 而不是getClass.getName

    还有另一种选择。您还可以使用getClass.getCanonicalName,它将$ 替换为.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 2012-05-09
      • 2020-04-01
      • 1970-01-01
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多