Scala の Class と Object にはなぜ同じ名前を付けるのか?

イシュー

  • 例えばこんなん
case class Company(id: Option[Long], name: String)

class Companies(tag: Tag) extends Table[Company](tag, "COMPANY") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name", O.NotNull)
  def * = (id.?, name) <> (Company.tupled, Company.unapply _)
}

object Companies {
  
  val companies = TableQuery[Companies]
  
  /**
   * Construct the Map[String,String] needed to fill a select options set
   */
  def options(implicit s: Session): Seq[(String, String)] = {
    val query = (for {
      company <- companies
    } yield (company.id, company.name)).sortBy(_._2)
    
    query.list.map(row => (row._1.toString, row._2))
  }

}

参考

コンパニオンクラス・コンパニオンオブジェクト

  • シングルトンオブジェクトがクラスと同じ名前を持つとき、そのクラスはコンパニオンクラスと呼び、オブジェクトの方はコンパニオンオブジェクトと呼ぶ。
  • コンパニオンクラスとオブジェクトは同じソースファイル内に定義しなければならない。
  • コンパニオンクラスとオブジェクトはお互いのprivateにアクセスすることが出来る。
  • object(シングルトンオブジェクト)を定義しても、型を定義できるわけではない。型はシングルトンオブジェクトのコンパニオンクラスによって定義される。(クラス型の変数をつくることが出来ない)

参考

なぜコンパニオンクラスなどをつくったか

  • おそらく、クラス名からインスタンスを生成する表現を使いたかったから
    • これはjavascriptなど動的言語では当たり前だが、javaではできない。(クラスはnew する必要があるため)
val a = List(1, 2, 3)