• ログインログイン
  • 新規登録新規登録

MENU

流行の技術に実際に触れてみよう 「Scala」と「PlayFramework」(4)

連載流行の技術に実際に触れてみよう 「Scala」と「PlayFramework」

ScalaとはJVM上で動作する関数型オブジェク指向言語です。簡潔な文法と実効速度に定評があり、国内でも徐々に浸透してきています。 流行の技術に実際に触れてみながら、動くものを作っていく開発レシピです。

前回までのプログラミング学習コラムに続き4回目の勉強内容です。

前回はScalaの関数型言語としての機能を紹介させて頂きましたが、今回はScalaのオブジェクト指向の機能を見ていきたいと思います。オブジェクト指向の機能と言うことでクラス、object[機能]、コンパニオン、トレイトを紹介させて頂きます。

クラス

Scalaのクラスは一点を除けば他の言語のものと大きく変わることはありません。その一点とは Java や C++ にある、静的●●( static )を仕様できない点です。代わりに objectという機能を使うのですが、こちらは後ほど改めて紹介させて頂きます。ここではクラスの基本的な機能を流していきましょう。

  • コンストラクタ

まず最初に、ScalaとJavaのコンストラクタで異なる点は多いです。 いつもどおり、サンプルコードを比較してみましょう。

// User.java
public class User{
 private final int id;
 private final String name;
 private int age;
 public User( int id, String name, int age){
 this.id = id;
 this.name = name; 
 this.age = age;
 }
 public int getId(){
 return id;
 }
 public String getName(){
 return name;
 } 
 public void setAge( int age ){
 this.age = age;
 }
}
// User.scala
class User( val id:Int, val name:String, var age:Int){
}

以上です。 解説しますと、Scalaのコンストラクタはクラス名の後に()を書く形で定義を行います。(省略可能) コンストラクタとして受け取った引数に var もしくは val が含まれている場合は自動でクラスのメンバー変数にします。 また、Scalaはアクセス演算子を指定しなければPublicになるので、GetterやSetterは設定しなくても使えます。

  • アクセス演算子 基本的に関数・変数の前に public , privateprotected を付ければ他の言語と同様に動作します。
  • 継承 いつもどおりJavaのコードと比較させて頂きます。実際にコードを見て頂くとわかりやすいかと思います。
//Super.java
public class Human{
 protected String name = 0;
 public void printAge(){
 println("my name is " + name)
 }
}
//Tanaka.java
public class Tanaka extends Human{
 public Tanaka(){
 super();
 name = "Tanaka";
 }
}
// Super.scala
class Human{
 protected var name
 def printAge = println("my name is " + name )
}
class Tanaka extends Human(){
 name = "Tanaka"
}

いつもどおり、Extendsで継承することが可能で基底クラスの宣言の後に()で基底クラスのコンストラクタを呼び出せます。

  • object

Scala のオブジェクトという機能を紹介させて頂きます。こちらはJavaやPythonなど他の言語には無い機能です。 デザインパターンのシングルトンをイメージして頂けるとわかりやすいと思います。 コードを比較しましょう。

//Sample.java
class Sample{
 private static Sample instance = null;
 private Sample(){}
 public static Sample getInstance(){
 if(instance == null)
 instance = new Sample()
 return instance;
 }
}
//Object.scala
object Sample{}

以上になります。 objectを使うと1つだけのインスタンスのオブジェクトを作ることができます。 static がなくてもこちらを使えばインスタンスを生成せずにメソッドや変数を使用できます。 これはグローバル変数の代わりのように使用する事ができてしまうので、使用にあたっては細心の注意が必要になりますが、うまく使用するとすごく便利な機能になります。

  • コンパニオン

先ほど、Scalaではstaticな静的●●が使用できないと言いましたが、半分嘘で半分本当です。 実はクラスとobjectを組み合わせるとコンパニオンという形でstaticを再現することができます。

object Companion{
 val pub = "publicObject"
 private val pri = "privateObject"
 def printPub = println(pub)
 def main(arg:String[]){
 val companion = new Companion
 companion.printAll
 }
}
class Companion{
 val pub = "publicClass"
 private val pri = "privateClass"
 def printPubClass = println(pub)
 def printAll = println(Companion.pub + Companion.pri + pub + pri)
}

これで静的変数を持つクラスを作ることができました。

  • trait

トレイトは他の言語にもサポートされている機能でよくinterfaceと比較されます。 interface との大きな違いは実装を持つことができる点です。

trait Name{
 val name = "hoge"
 def printName:Unit
}
trait Age{
 val âge = 1
 def printAge:Unit
}
class Human extends Name with Age{
 def printName:Unit= println(name)
 def printAge:Unit=println(age)
}

トレイトは実装も状態も持つことが可能です。 例えば、今回の例で言えばHumanの中でageやnameの中を書き換えると関数の実行結果も変わります。 関数の実装を全部トレイトに書いて、必要なメンバーの宣言だけトレイトをミックスインしたクラスで行うとすっきりとした設計にできるのではないかと思います。

まとめ

今回はScalaのオブジェクト指向の機能を中心に紹介させて頂きました。 ScalaのTraitやコンパニオン、クラスはとても奥深い機能で今回紹介できた部分はほんのわずかです。 ぜひとも、書籍『Scalaスケーラブルプログラミング』などScala本を読んでより深い所を探索していただければと思います。

オススメ記事一覧

もっと見る
完全無料!

1で登録完了!

エンジニアの仕事・年収や選考ノウハウ記事が読めるほか、
会員にはプログラミング講習やES・面接対策などリアルな無料サポートも充実。
ここだけの求人情報も多数。

今すぐ新規会員登録
Page Top