【问题标题】:Getting error when instantiating a trait within a class (method became private)在类中实例化特征时出错(方法变为私有)
【发布时间】:2018-12-29 04:52:18
【问题描述】:

在以下代码中,我尝试使用 Decorator 类实例化特征 A 并向其添加方法 p,以便我可以使用 p 方法获取另一个对象 A:

trait A {
  def x: Int
}

case class Decorator(a: A) {
  def withPrint: A = new A {
    val x = 100
    def p: Unit = println(x)
  }
}

val a = new A {val x = 100}

val d = Decorator(a).withPrint

但是当我尝试调用d.p 时会出错

值 p 不是 A$A54.this.A 的成员

然后我在d 中打印声明的方法我看到pprivate

d.getClass.getDeclaredMethods.foreach(println)

# public int stringsimilarity.A$A55$A$A55$Decorator$$anon$2.x()
# private void stringsimilarity.A$A55$A$A55$Decorator$$anon$2.p()

谁能解释为什么会这样?任何帮助将不胜感激!谢谢!

【问题讨论】:

    标签: scala access-modifiers anonymous-inner-class


    【解决方案1】:

    def p 没有理由公开。这是您在实现特征A 的本地匿名类中定义的方法。特征A 仅声明公共方法x,没有别的。因此,您可以访问 p 的唯一范围是在 new A { ... } 的初始化程序内部,因此 private 似乎适合此。

    如果你想公开方法p,你可以将它添加到A(然后你必须在那里实现它,然后你也根本不需要withPrint方法),或者混合一个额外的特征来保证方法p的存在。例如:

    trait A {
      def x: Int
    }
    
    trait Print {
      def p: Unit
    }
    
    case class Decorator(a: A) {
      def withPrint: A with Print = new A with Print {
        val x = 100
        def p: Unit = println(x)
      }
    }
    
    val a = new A { val x = 100 }
    
    val d = Decorator(a).withPrint
    
    d.p
    

    【讨论】:

    • 谢谢安德烈!使用 mixin 更有意义,你就是男人!
    • 如果我们通过删除trait Printcompletely 和withPrint 方法中的with Print mixin 直接在trait A 中添加def p: Unit 抽象方法是否有效。?如果我们在特征 A 中添加 implemented method p 而不是使用抽象方法,它会起作用..你能澄清一下这个 Andrey Tyukin 吗?
    • @RAGHHURAAMM 如果我们将def p: Unit添加到trait A,那么我们必须在实例化val a = new A { ... }时提供它,也就是说,我们要么必须将它包含在trait A { ... }中从头开始,或将其添加到每个new A { ... }。在这两种情况下,withPrint 方法本身都变得无用。所以,如果你想保留 withPrint 做一些半途而废的事情,我不知道如何避免混合或改进返回类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2015-04-18
    • 1970-01-01
    相关资源
    最近更新 更多