ホーム DoRuby rubyistのためのscala (3) クラスとオブジェクト指向

rubyistのためのscala (3) クラスとオブジェクト指向

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回はクラスとオブジェクト指向について。

クラス

クラスの宣言と継承

Ruby

class Foo < Bar
end

Scala

class Foo extends Bar {
}

コンストラクタ

Rubyではinitializeという名前のメソッドを定義する。

class Foo
  def def initialize(bar)
    # new した時点でここが実行される
  end
end

Scalaにはコンストラクタを複数定義できるが、ここではデフォルトのコンストラクタについて説明する。

デフォルトのコンストラクタはクラス定義のブラケット内にそのまま記述できる。
引数はクラス名の後ろのカッコ内に書く。

class Foo(bar: Int) {
  // new した時点でここが実行される
}

モジュール

Ruby

module Foo
  def bar
  end
end

Scala

trait Foo {
  def bar: Unit = {
  }
}

barというメソッドを持つtrait Fooを定義することができる。

Mixin

Scalaではtraitを継承することでmixinを行う。

Ruby

module Bar
end

class Foo
  include Bar
end

Scala

trait Bar {
}

class Foo extends Bar {
}

ひとつのクラスが複数のtraitをmixinする場合、二つ目以降は with というキーワードを使う。

Scala

class Foo extends Bar with Baz with Hoge {
}

TODO: prependusingについても調べて書く

名前空間

Rubyではモジュールを名前空間として使うことができる。

Ruby

module Foo
  module Bar
    class Baz
    end
  end
end

baz = Foo::Bar::Baz.new

Scalaではパッケージのほか、シングルトンオブジェクトも名前空間として使うことができる。

Scala

package foo
object Bar {
  class Baz {
  }
}

val baz = new foo.Bar.Baz()

TODO: import について書く

メソッド

キーワードは同じ def
引数と返り値の型を指定する。

Ruby

class Foo
  def bar(a, b)
    a + b
  end
end

Scala

class Foo {
  def bar(a: Int, b: Int): Int = {
    a + b
  }
}

プロパティとアクセサ

デフォルトのゲッター、セッター

Ruby

class Foo
  attr_accessor :bar, :baz
  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end
end

foo = Foo.new(1, "abc")
foo.bar  # => 1
foo.baz  # => "abc"

Scala

class Foo(var bar: Int, var baz: String) {
}

val foo = new Foo(1, "abc")
foo.bar  // => 1
foo.baz  // => "abc"

セッターの実装

Ruby

class Foo
  attr_reader :bar
  def bar=(i)
    @bar = i
  end
end

foo = Foo.new
foo.bar = 1
foo.bar  # => 1

Scala

class Foo {
  private var _bar: Int = _
  def bar = _bar
  def bar_=(i: Int): Unit = this._bar = i
}

val foo = new Foo()
foo.bar = 1
foo.bar  // => 1

Scalaのセッターメソッドは def 変数名_=(引数): Unit = ??? という形で定義する。

演算子メソッド

Rubyでメソッドとして再定義可能な演算子

|  ^  &  <=>  ==  ===  =~  >   >=  <   <=   <<  >>
 +  -  *  /    %   **   ~   +@  -@  []  []=  ` ! != !~

Scalaで再定義できない予約語、キーワード
FAQ How do I find what some symbol means or does?より引用)
(これ以外の記号、英数字は使えるらしい)

// Keywords
<-  // Used on for-comprehensions, to separate pattern from generator
=>  // Used for function types, function literals and import renaming
// Reserved
( )        // Delimit expressions and parameters
[ ]        // Delimit type parameters
{ }        // Delimit blocks
.          // Method call and path separator
// /* */   // Comments
#          // Used in type notations
:          // Type ascription or context bounds
<: >: <%   // Upper, lower and view bounds
" """      // Strings
'          // Indicate symbols and characters
@          // Annotations and variable binding on pattern matching
`          // Denote constant or enable arbitrary identifiers
,          // Parameter separator
;          // Statement separator
_*         // vararg expansion
_          // Many different meanings

どちらも記号を名前としたメソッドを定義することで演算子を定義できる。

class Foo
  def +(other)
    "add method"
  end
end

foo1 = Foo.new
foo2 = Foo.new
foo1 + foo2  # "add method"
class Foo {
  def +(other: Foo): String = "add method"
}

val foo1 = new Foo
val foo2 = new Foo
foo1 + foo2  // "add method"

引数のデフォルト値

Ruby

class Foo
  def bar(baz = 1)
    baz
  end
end

foo = Foo.new
foo.bar()  # => 1
foo.bar(2)  # => 2

Scala

class Foo {
  def bar(baz: Int = 1): Int = {
    baz
  }
}

val foo = new Foo()
foo.bar()  // => 1
foo.bar(2)  // => 2

可変長引数

Rubyでは定義するときも呼び出すときも * という記号をまえにつける。

class Foo
  def bar(baz, *hoge)
    # 2つめ以降の引数はhogeに配列として入る
  end
end

foo = Foo.new
baz = 1
hoge = ["foo", "bar"]
foo.bar(baz, *hoge)

Scalaでは定義するときは *をうしろにつけ、呼び出すときは :_* という記号をうしろにつける。

class Foo {
  def bar(baz: Int, bar: String*): Unit = {
    // 2つめ以降の引数は bar にSeqとして入る
  }
}

val foo = new Foo
val baz = 1
val hoge = Seq("foo", "bar")
foo.bar(baz, hoge:_*)

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

記事を共有

最近人気な記事