抽象クラス・インターフェース
Java 2015/04/02
抽象クラス(abstract class)の例
public abstract class AbstractHoge {
protected String hogeField;
// 抽象メソッド定義
public abstract void fooMethod(String s);
// メソッド実装
public void barMethod(String s) {
...;
}
}
インターフェース(interface)の例
public interface IHoge {
// 抽象メソッド定義
public void fooMethod(String s);
// Java8から書けるメソッドのデフォルト実装
public default void barMethod(String s) {
...
}
}
- 抽象クラスの多重継承はできないが、インターフェースの多重継承はできる。 抽象クラス1つとインターフェース1つ以上を同時に継承することもできる。
- 抽象クラスはフィールドを定義できるが、インターフェースはフィールドを定義できない。
- 抽象クラスはコンストラクタを定義できるが、インターフェースはコンストラクタを定義できない。
- インターフェースのメソッドは
abstract
を付けなくてもすべて実装のない抽象メソッドになる。
Java8からの機能 2014/10/27
Java7までは実装を持つメソッドをインターフェースに定義できないが、
Java8からはデフォルト実装というものを持つことができる。デフォルト実装を持つメソッドには修飾子として default
と書く。
Object
クラスが実装を持っているメソッド、例えば equals
などはデフォルト実装を定義できない。
複数のインターフェースを継承しようとし、その中に、デフォルト実装を持つ同じシグニチャのメソッドが重複していて、サブクラスに実装がない場合は、コンパイルエラーになる。その場合はサブクラスに IHoge.super.barMethod(s);
のような実装を書くことでいずれかのインターフェースの実装を呼び出すようにする。
また、Java8からはインターフェースにstaticメソッドを定義することもできる。
staticメソッドには default
の修飾子は不要。
Java8で、Objectが持つメソッドについてはインターフェースでdefault実装をできないようにしている理由
http://namihira.hatenablog.com/entry/2014/10/26/202423
Scala 2014/10/27
Javaと同様の抽象クラス(abstract class)ののほかにJavaのインターフェース(interface)に似たトレイト(trait)がある。
抽象クラス(abstract class)の例
abstract class AbstractHoge {
protected[this] val hogeField = ...;
def fooMethod(s: String);
def barMethod(s: String) {
...;
}
}
トレイト(trait)の例
trait Hoge {
def fooMethod(s: String);
// Java8のインターフェースのデフォルト実装みたいなものは普通にできる
def barMethod(s: String) {
...
}
}
- 抽象クラスの多重継承はできないが、トレイトの多重継承はできる。 抽象クラス1つとトレイト1つ以上を同時に継承することもできる。
- 抽象クラスもトレイトもフィールドを定義できる。
- トレイトはクラスパラメータを持てない(コンストラクタにパラメータを持てない)。 トレイト定義の中にステートメントを書くことで、コンストラクタの処理を書くことはできる。
- 抽象クラスもトレイトも、実装のないメソッドは抽象メソッドになる。