効果的なJavaでは、JoshuaBlochは抽象クラスよりもインターフェースを優先します。ただし、彼は、骨格の実装はすべてのインターフェースに付属している必要があると述べています。
骨格の実装は抽象クラスとほとんど同じだと思います。これらの2つの概念はどのように異なりますか?
効果的なJavaで前述のセクションを読み直した後に編集
本のこのセクションによると、骨格の実装は抽象クラスです。彼はこのアプローチを推奨しています。なぜなら、骨格の実装が行われた後、匿名のクラスであっても、インターフェースを実装し、メソッドを選択的にオーバーライドするのは簡単になるからです(彼の本でそうしています)。
前の回答、継続性のためにわずかに編集
骨格の実装は、理論的には完全な実装であり、したがって具体的である可能性があります。次に、インスタンス化できるため、コンポジションで使用できます。一方、抽象クラスには継承が必要です。
彼が意味するのは、インターフェースと、このインターフェースの一部を実装する抽象クラスを提供する必要があるということです。
public interface Foo {
void bar();
void baz();
}
private abstract class AbstractFoo implements Foo {
...
}
基本的で完全な実装を提供できる場合、AbstractFoo
クラスは抽象的ではない場合もあります。ただし、Fooであるが、AbstractFooを拡張できないクラスが必要な場合でも、インターフェースを使用してそれを行うことができます。抽象クラスは、1つのクラスしか拡張できないため、この機能を提供しません。
ところで、これは(Josh Blochが作成した)コレクションフレームワークで行われることです。Set
インターフェイスはによって実装されAbstractSet
、List
インターフェイスはによって実装されますAbstractList
。
インターフェイス/抽象クラスはAPIの一部です。
骨格の実装は有効な具体的なものですclass
が、限定的/ナイーブ/不十分な実装です。Sorter
(非常に工夫された)例では、インターフェースの骨格実装はバブルソートを実装する可能性があります-実稼働アプリケーションでは使用したくないでしょうが、インターフェースを実装する方法を示しています
骨格の実装は抽象クラスとほとんど同じだと思います。これらの2つの概念はどのように異なりますか?
私にとって、それらは意図が異なります。あるメソッドがインターフェースが渡されることを期待しているのを見ると、実装は私次第であることがわかります。クラスが返された場合、私はもうわかりません。クラスには存在しないインターフェースを使用することには、単に意味があります。
また、引数のクラスを受け入れるメソッドは、渡したいクラスがすでにサブクラスである場合に競合を招きます。Javaは多重継承をサポートしていません。インターフェイスにはこの問題はありません。
「骨格の実装」は具体的なクラスです。コンパイルしてテストすることができます。
抽象クラスはそうではありません、そしてあなたはできません;)