代码之家  ›  专栏  ›  技术社区  ›  Axel

伴随对象实现接口的可能性的好处

  •  3
  • Axel  · 技术社区  · 7 年前

    为什么在Kotlin/Scala中,伴随对象可以实现一些接口,这有什么好处?何时使用此功能有用?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Alexey Romanov    7 年前

    因为 companion object s是 object s 对象 s可以实现接口(或扩展类),因此没有理由不允许它 伴星 特别是s。

    Scala中的一个常见用途是用于工厂:例如。 Seq , List , Vector 等。伴生物体均延伸 TraversableFactory 因此,您可以使用 可遍历工厂 并传递其中任何一个来构造所需的类型。例如。

    def build[CC[X] <: Traversable[X] with GenericTraversableTemplate[X, CC], A](factory: TraversableFactory[CC])(elems: A*) = factory(elems)
    
    // build(List)(1,2,3) == List(1, 2, 3)
    // build(Set)(1,2,3) == Set(1, 2, 3)
    

    类似地,所有case类伴随对象都扩展了函数类型。

        2
  •  3
  •   Kirill Rakhman    7 年前

    您可以使用 companion object

    示例1:工厂

    考虑一个接口

    interface Factory<T> {
        fun create(): T
    }
    

    现在,我们创建一个类,它的伴随对象实现了它

    class Foo {
        companion object: Factory<Foo> {
            override fun create() = Foo()
        }
    }
    

    现在我们可以为所有工厂创建一个扩展函数来创建和记录对象。

    fun <T> Factory<T>.createAndLog(): T {
        val t = create()
        println(t)
        return t
    }
    

    然后像这样使用它

    Foo.createAndLog()
    

    示例2:查询

    考虑标记接口

    interface Queryable<T>
    

    我们现在有两个班 User Article 表示数据库中的表 伴星 实现接口。

    class User(val id: String) {
        companion object: Queryable<User> {}
    }
    
    class Article(val authorId: String) {
        companion object: : Queryable<Article> {}
    }
    

    我们现在可以定义一个扩展函数来从类中创建查询

    fun <T> Queryable<T>.query() = db.createQuery<T>()
    

    我们可以称之为

    User.query()
    //or
    Article.query()
    
        3
  •  1
  •   insan-e    7 年前

    当您只需要程序中特定类的一个实例时,可以使用单例对象。

    E、 g.Scala's公司 Nil 机具 List[Nothing] . 而不是要实现的每种类型的列表 这很特别 只有一个。

    在里面 typeclass pattern ,你只有一个 implicit object 用于相应的实施。

    此外,您还可以创建一个 public static Something 在Java中,您可以在一个伴随对象中创建它。

    我个人发现它们对于实现sbt插件非常有用,该插件可以呈现 object Blah extends Renderable 到文件 blah.html . 了解更多有用信息 here . 我 必须知道它实现了 那个特点!