Scala类的限制构造

Scala类的限制构造,scala,Scala,鉴于: 除了将Foo的构造函数标记为private,在调用newfoo(…)时,如何显示警告或编译时失败 换句话说,我想将Foo的构造(通过编译时警告或错误)限制为Foo.apply 这可能吗?在scala中,有两种惯用的方法来实现这一点 类和伴随对象的私有构造函数 工厂有权访问构造函数,而其他任何人没有: class Foo(x: Int) {} object Foo { def apply(x: Int) = new Foo(x) } 密封的抽象类 在scala中,sealed类只能

鉴于:

除了将
Foo
的构造函数标记为
private
,在调用
newfoo(…)
时,如何显示警告或编译时失败

换句话说,我想将
Foo
的构造(通过编译时警告或错误)限制为
Foo.apply


这可能吗?

在scala中,有两种惯用的方法来实现这一点

  • 类和伴随对象的私有构造函数
  • 工厂有权访问构造函数,而其他任何人没有:

    class Foo(x: Int) {}
    
    object Foo {
      def apply(x: Int) = new Foo(x)
    }
    
  • 密封的抽象类 在scala
    中,sealed
    类只能在定义它的同一源文件中扩展。 我建议创建
    Foo
    密封的抽象类
    ,并在对象的apply方法中返回
    Foo
    的匿名子级

    class Foo private[Foo](val x: Int)
    
    object Foo {
      def apply(x:Int) = new Foo(x)
    }
    
    val foo = new Foo(1)  // cannot compile
    val foo1 = Foo(1) //compiles fine
    
    在这种情况下,
    Foo
    只能在定义它的文件中创建

    UPD:事实上,这个问题已经解决了


    UPD2:添加了两种方法的简要概述。

    在scala中,有两种惯用方法可以实现这一点

  • 类和伴随对象的私有构造函数
  • 工厂有权访问构造函数,而其他任何人没有:

    class Foo(x: Int) {}
    
    object Foo {
      def apply(x: Int) = new Foo(x)
    }
    
  • 密封的抽象类 在scala
    中,sealed
    类只能在定义它的同一源文件中扩展。 我建议创建
    Foo
    密封的抽象类
    ,并在对象的apply方法中返回
    Foo
    的匿名子级

    class Foo private[Foo](val x: Int)
    
    object Foo {
      def apply(x:Int) = new Foo(x)
    }
    
    val foo = new Foo(1)  // cannot compile
    val foo1 = Foo(1) //compiles fine
    
    在这种情况下,
    Foo
    只能在定义它的文件中创建

    UPD:事实上,这个问题已经解决了


    UPD2:添加了两种方法的简要概述。

    为什么“除了将Foo的构造函数标记为私有之外”?该解决方案有什么问题?这就是将构造函数标记为私有的原因。值类忽略私有,否?@KevinMeredith,否。检查我答案的更新,并按照其中的链接了解更多详细信息。为什么“除了将Foo的构造函数标记为私有”?该解决方案有什么问题?这就是将构造函数标记为private的原因。值类忽略private,否?@KevinMeredith,否。请检查我答案的更新,并按照其中的链接了解更多详细信息。但是,
    抽象类
    无法实例化。@KevinMeredith,这就是重点。在
    对象Foo
    中,您可以创建objec扩展
    Foo
    (这就是为什么
    newfoo
    后面有大括号的原因),而在其他文件中,你不能这样做,因为
    Foo
    是抽象和密封的,这意味着你不能直接创建它,也不能扩展它来实例化它的子类。但是
    抽象类不能实例化。@KevinMeredith,这就是重点。在
    object Foo
    中,你可以创建匿名类的对象扩展
    Foo
    (这就是为什么在
    new Foo
    之后有大括号),而在其他文件中你不能这样做,因为
    Foo
    是抽象和密封的,这意味着你不能直接创建它,也不能扩展它来实例化它的子文件。