Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
84
Help us understand the problem. What is going on with this article?
@f81@github

第9章:Scalaのトレイト(trait)

More than 5 years have passed since last update.

今回はトレイトについて語ってみるよ。
トレイトがわかると実装の可能性が広がるから、やってみよう!

Scalaのトレイト

まずは トレイト の感じを掴んでみYO!

色々な意見があるかもしれないけど、トレイトをこういうモノだと思っている。

機能を切りだして、再利用可能な塊にしたモノ

トレイトはJavaのインタフェース(interface)に近いモノという説明もある。
確かに、Javaのインタフェースのように使えると思うんだけど
なんかスッと入ってこないんだよね。
まだまだScalaの修業が足りないせいかもしれない。

トレイトの特徴

Scalaのトレイトには、以下な大きな特徴があるよ。

  • traitキーワードで定義
  • クラスパラメータを取ることができない
  • メソッドを実装できる
  • クラスや他のトレイトにミックスインできる
  • 任意の数をミックスインできる
  • 純粋ではないが多重継承ぽさがある

この特徴に沿って説明してみるね。

traitキーワードで定義

早速トレイトを定義してみよう。

scala> trait Job
defined trait Job

なんと、これだけでJobというトレイトが定義できてしまった。
トレイトを作ることはもう簡単だね!

クラスパラメータを取ることができない

クラスは以下のようにクラスパラメータを定義できるよね?

scala> class Job(name: String)
defined class Job

同じことをトレイトでやってみると

scala> trait Job(name: String)
<console>:1: error: traits or objects may not have parameters
       trait Job(name: String)
                ^

コンパイルエラーが発生してしまうんだ。
これってつまりは、パラメータによる初期化ができないってことなんだよね。

でもこんな感じで、パラメータを受け取って初期化できるよ。

scala> trait Job { val name: String }
defined trait Job

scala> new Job { val name = "student" }
res0: Job = $anon$1@518677ee

scala> res0.name
res1: String = student

もう1つ。

scala> trait Job { val name: String }
defined trait Job

scala> new { val name = "student" } with Job
res2: Job = $anon$1@701ce28a

scala> res2.name
res3: String = student

メソッドを実装できる

次にメソッドを追加してみるよ。

Human.scala
trait Job {
  def getName() {
    "student"
  }
}

どう?Javaのインタフェースでは、getNameメソッドのように実装を持つことはできないよね。
もうこの時点でJavaのインタフェースとの違いが出てきていました。

これが、機能を切り出すために実現されているコトの1つだよ。

クラスや他のトレイトにミックスインできる

トレイトを使うところを見たい!ってなってきていますよね?
今度は、トレイトを使ってみるよ。
ここで ミックスイン が出てくるんだ。

ミックスイン

ミックスインとは、 複数のトレイトを使ってクラスやトレイトを定義する ことだ。
このことを ミックスイン合成 なんて言うこともある。
Javaのインタフェースで言うと、 複数のインタフェースを実装してクラスを定義する みたいな。

クラスやトレイトを定義するために 使用したトレイト のことをミックスインと言うこともある。

この辺、言語によっても違うみたいだし、捉え方によっても違うから難しいところだけど、
ここでは上記のような整理にするよ。

ミックスインしてみる

やってみるよ!

Trait1.scala
object Trait1 {
  def main(args: Array[String]){
    val man = new Man
    man.say()
  }
}

trait Human {
  val name = "飛行帽"

  def sayName() {
    println("My name is " + name)
  }
}

class Man extends Human

ここでは、HumanトレイトをミックスインしてクラスManを作っている。
ここではミックスインする時に、extendsを使っている。
実はextendswithキーワードでミックスインする。

  • extendsの場合は、他のクラスを継承しない場合に使用する。指定したトレイトのスーパークラスが暗黙の継承クラスとなる。スーパークラスが存在しない場合は、AnyRefクラスとなる。1つしか指定できないため、その他のトレイトはwithで指定する。
  • withの場合は、extendsを指定済みで、他のトレイトを指定する場合に使用する。

任意の数をミックスインできる

もう先に書いたけど、withキーワードを使って複数のトレイトをミックスインすることもできるんだ。

Trait2.scala
object Trait2 {
  def main(args: Array[String]){
    val man = new Man("虎丸龍次", "男塾", "一号生")
    man.say()
  }
}

trait Human {
  val name: String
}

trait Job {
  val job: String
}

trait Grade {
  val grade: String
}

class Man(n: String, j: String, g: String) extends Human with Job with Grade {
  val name = n
  val job = j
  val grade = g

  def say() {
    println("名前は" + this.name + "じゃ。" + job + grade + "じゃ。")
  }
}

純粋ではないが多重継承ぽさがある

Scalaの継承は、単一継承のみで多重継承はサポートしていないんだ。
でもトレイトを使うと、多重継承ぽくできるみたいなんだ。

ここはゴメンナ。
実は多重継承をやったことないから、イメージがわかないんだ。

まとめ

今回は、 トレイト について語ってみたけど、掴むことができたかな?
もちろんトレイトにもまだまだ色々あるから調べてね。

トレイトを使いこなすには、モデリングとデザインの部分も重要だと思うよ。

今回も
体で感じてくれたかな?

84
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
f81@github
Fringe81のエンジニアが頑張って執筆ちゅうです! Scala の修行を始めました。 みなさま、温かい目で見守ってください。
fringe81
Fringeは、最新のテクノロジーとプロフェッショナルによるサービスにより、社会課題に仮説を立てて市場に広げていくことで、数十年という長期的なスパンで価値を生み出し続け、より良い世界を創る集団です。 既存の領域に限らず、時流を読み、仮説を生み出し、テクノロジーの力で優れたサービスを生み出し続けます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
84
Help us understand the problem. What is going on with this article?