如何调用受限访问的子类构造函数?

问题描述:

我有类似下面,我想编译如何调用受限访问的子类构造函数?

trait T{ 
    def a: Int 
} 

class A private(val a: Int, a2: Int) extends T{ 
    def add(b: Int): A = new A(a + b, a2 + 2*b) 
} 

object T{ 
    def make(a: Int): A = { 
    new A(a, 2*a) // doesn't compile 
} 

这里类A有一个私有构造函数,因为我想构建一个一个的唯一方法是通过构造T.make或用更新的方法A.add(在这个例子中,它们都是a 2 = 2 * a)。

但是因为构造函数是私有的,所以它不能被父特征T访问。同样也适用于受保护的。基本上,我需要一个反向保护?

注意:不令人满意的解决方案是降低(太多)对构造函数的限制,可能是封装私有。但我不希望任何其他的工程可能,但那些计划中的工程。我可以降低当前文件中所有代码的约束,但是我不知道该怎么做。

+0

它应该工作。见[这里](https://*.com/questions/6919965/companion-object-cannot-access-private-variable-on-the-class)。此外,对于最佳做法,请参阅[此处](https://*.com/a/30836828/5599298) – slouc

+0

@slouc您的第一个链接与REPL中的行为相关(第二个链接是正常的)。 –

+2

关于最佳做法,这只是个人喜好,为建造者功能(make,build,...)提供明确的名称。我用备用构造函数继续应用()大小写类/纯定义类。这里不是我的情况,但我可以在示例 –

有几个选项。

  • 您可以重命名object Tobject A - 那么它将有机会获得A的私有成员

  • 您可以class A内到object T - 那么你可以让构造private[T],并T将有机会获得到它。

  • 你也可以使它成为私有包。当你说它会“降低限制太多”时,你是错误的。 scala中的包不一定是整个目录。它甚至不需要是整个文件。您可以完全控制其内容,其目的是能够完成您在此尝试完成的任务。

+0

我不知道'私人[T]范围 –

也许你应该把make(..)放入类A的伴侣对象,而不是特质T的伴侣对象。

object A { 
    def make(a: Int): A = { 
     new A(a, 2 * a) 
    } 
    } 
+1

中使用它确实有效。我(显然)有一个更复杂的情况下,这不是很实际(例如:我有另一个T子类和公共构造函数与A构造函数共享功能)。但我可以找到我的出路 –