在类中实例化特征时出错(方法变为私有)

Posted

技术标签:

【中文标题】在类中实例化特征时出错(方法变为私有)【英文标题】: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()

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

【问题讨论】:

【参考方案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 做一些半途而废的事情,我不知道如何避免混合或改进返回类型。

以上是关于在类中实例化特征时出错(方法变为私有)的主要内容,如果未能解决你的问题,请参考以下文章

python-- 类的实例化过程特征共有属性和私有属性

单体设计模式

构造私有化和单例设计模式

python的类定义与实例化

单例模式工厂模式

用java反射实例化私有内部类