LoginSignup
1
1

More than 5 years have passed since last update.

java のクラスを scala で継承

Last updated at Posted at 2016-07-03

scala で java のクラスを継承するときに気をつけること

  • package と import, コンパイル時のクラスパス
  • java 側のクラスと scala 側のクラスのコンストラクタ引数の一致

以下のようなディレクトリ構造,ファイルで検証

tree
# => 現在のディレクトリ構造
# .
# ├── class
# ├── lib
# │   ├── java
# │   │   └── Super.java
# │   └── scala
# │       └── Sub.scala
# └── src
#     └── Main.scala
# 
# 5 directories, 3 files
/lib/java/Super.java
package lib.java;

public class Super {
  private String name;

  public Super(final String name) { this.name = name; }

  public String getName() { return this.name;  }
  public String greet() { return "Hello from " + this.getName() + " in Super"; }
}
/lib/scala/Sub.scala
package lib.scala

import lib.java.Super

final class Sub(val name :String) extends Super(name :String) {
  override def greet() :String = "Hello form " + this.getName + " in Sub"
}
/src/Main.scala
import lib.java.Super
import lib.scala.Sub

object Main {
  def main(args: Array[String]) {
    val a :Super = new Super("A")
    val b :Sub   = new Sub("B")

    println(a.greet)
    println(b.greet)
  }
}

package と import, コンパイル時のクラスパス

コンパイルすると package に記述したディレクトリ構造でクラスファイルが生成される.
また,import するクラスが存在するソースをコンパイルする時は,適切にクラスパスを指定する必要がある.
libファイルやsrcファイルなど存在するディレクトリが異なる依存関係の時は,javac, scalac のコマンドオプションを使えばきれいに解決.

-classpath <path> : ユーザのクラスファイルを <path> から探索
-d <directory>    : 生成したクラスファイルを置くディレクトリを <directory>  に設定

java 側のクラスと scala 側のクラスのコンストラクタ引数の一致

引数が上記の ./lib/scala/Sub.scala のように一致していないとコンパイル時にエラー

# scalac ./lib/scala/Sub.scala

# final class Sub extends Super の時

<path>/lib/scala/Sub.scala:5: error: not enough arguments for constructor Super: (x$1: String)lib.java.Super.
Unspecified value parameter x$1.
final class Sub(val name :String) extends Super {
                                          ^
one error found

# final class Sub extends Super(name :String) の時

<path>/lib/scala/Sub.scala:5: error: not found: value name
final class Sub extends Super(name :String) {
                              ^
one error found

コンパイル&実行

root=`pwd`

# 依存順にコンパイル
javac -d ${root}/class ${root}/lib/java/Super.java &&
scalac -classpath ${root}/class -d ${root}/class ${root}/lib/scala/Sub.scala &&
scalac -classpath ${root}/class -d ${root}/class ${root}/src/Main.scala

tree
# .
# ├── class
# │   ├── Main$.class
# │   ├── Main.class
# │   └── lib
# │       ├── java
# │       │   └── Super.class
# │       └── scala
# │           └── Sub.class
# ├── lib
# │   ├── java
# │   │   └── Super.java
# │   └── scala
# │       └── Sub.scala
# └── src
#     └── Main.scala
# 
# 8 directories, 7 files


scala -classpath ${root}/class Main
# Hello from A in Super
# Hello form B in Sub

余談

手動ビルドだったので,sbt やら typesafe-activator を用いてやる方法もそのうち.
java のクラスを scala で継承 (typesafe-activator編) をあげました

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1