JavaからみたScalaの書き方

タイトルの通りです。
Scalaやりたくなったのでまとめてみました。
学習中に都度、更新予定。
ちなみに筆者の経歴はC#4年、Java1年です。

#命名規則
Javaと同じで良さそう。キャメルケース

#細かなルール
- 末尾セミコロン不要
- コメントは同じ //と/* */

#変数
宣言で型推論が効く！（Javaだと10から）

```scala
val hoge = 1 // imutable（不変。final付きの変数）
var hoge = 1 // mutable（可変）
```
型指定だと、

```scala
val i:Int = 1
val str:String = "Hi!"
```
文字列の中に変数を埋め込むには、リテラルの前にsをつけて変数に$をつける

```scala
val firstName = j
val familyName = ichikawa
val str = s"my name is $firstName - $familyName"
```
リテラル内にコードを埋め込むこともできる

```scala
val str = s"My weight　is ${weight + 3}"
```
#if文
書き方は同じ
値を返す式として書ける

```scala
val age = 30
val result =
  if (age >= 30) "over 30"
    else "under 30"
println(result)// over 30
```
#演算子
基本同じだけど、三項演算子はないみたい。ifで値を返せるので代用できる

```scala
val result = if (age >= 30) "over 30" else "under 30"
```
#switch
matchと言うらしい

```scala
val team = "ソ"
val result = team match {
  case "ロ" | "鴎" => "ロッテ" // or条件
  case other => s"undefined: ${other}" // default
}
println(result)
// undefined: ソ
```

#ループ
whileは同じだけど、forはちと異なる
条件をジェネレーターと言うらしい

```scala
for (i <- 0 to 3) println(i) // 条件を 0 until 4 で0以上4未満とできる
// 0
// 1
// 2
// 3

for (i <- 0 to 3 if i != 2) println(i) // 条件付き
// 0
// 1
// 3

var result = for (i <- 0 to 3) yield i // 結果を取得
for (i <- result) println(i)

for (i <- 0 to 3; j <- 0 to 3) println(s"$i, $j") // forの入れ子
```

#メソッド
javaだと、

```Java
public void sayHello() {
  System.out.println("hello");
}
    
public String sayHelloStr() {
  return "hello";
}
    
public String getHelloMessage(String firstName, String familyName) {
  return "Hello " + firstName + " " + familyName;
}
```
が、

```scala
def sayHello: Unit = {
  println("hello")
}
    
def getHelloStr: String = {
  "Hello" // return 省略可
}
    
def getHelloMessage(firstName: String, familyName: String): String = {
  s"Hello $firstName $familyName"
  // firstName: String = "taro" のようにデフォルト値を設定できる。C#と同じだ
}
```
#クラス

```scala
class Human(val name: String) { // パラメータ定義でコンストラクタになる
  def sayHello() = println("hello") // ラムダっぽいメソッド定義
}

// インスタンス化
val human = new Human（"j-ichikawa"）
val name = human.name;
human.sayHello()
```
継承は、

```scala
class PerfectHuman(name: String) extends Human(name) {
  override def sayHello() = println("perfect hello")
}

```
#パッケージ
宣言は同じ

```scala
package aaa.bbb.ccc
```
呼び出しは、

```scala
import aaa.bbb.ccc.ddd // 個別
import aaa.bbb.ccc.ddd.{ddd, eee} // 複数
import aaa.bbb.ccc.ddd._ // まとめて
```
#アクセス修飾子
public, protected, privateつけたクラスのメンバーへの付け方、見え方は同じ
何もつけないとデフォルトでpublicになる（C#だとprivateがデフォルトだよね
#final
クラス、メンバーにつけたときの働きはJavaと同じ。変数をimutableにするにはvalで宣言する

#object
型ではなく、キーワードらしい
同名のクラスにobjectをつける

```scala
// コンパニオンオブジェクトというみたい
object Human {
  def sayHello() = println("hello") // クラスメソッドのようにインスタンス化せず呼べる
  def apply(name: String) = new Human(name) // ファクトリーメソッドの定義になる
}

// こちらはコンパニオンクラス
class Human (val name: String) {
  def sayHello() = println("hello")
}

// コンパニオンオブジェクトの使い方
Human.sayHello()
val taro = Human("taro") // taroインスタンスの生成
```

printlnはPredefというオブジェクトのメソッドらしい

新しい概念。。

#抽象クラス
うん、抵抗なし

```scala
abstract class Animal {
  def cry()
}

class Cat extends Animal {
  def cry() = println("にゃあああ")
}
```

#インターフェイス
トレイトというらしい

```scala
trait Runnable {
  def run() = println("ダダダ。。。")
}

class Player extends Runnable // 実装 継承と同じ構文 C#と同じ
class SuperPlayer extends Player with Runnable // 継承していたらwithで実装

```

更新中。。。