1. 概要

このチュートリアルでは、 abstractclassesとtraitがScalaにあることと、それらの主な違いを確認します。

Scalaは、これらのメカニズムの両方を提供し、継承を通じて異なるクラス間で動作を再利用できるようにします。 彼らがそのタスクにどのように役立つかをさらに詳しく見てみましょう。

2. 抽象クラス

Scalaの抽象クラスは、Javaのクラスと非常によく似ています。 実際、Scala抽象クラスはJavaと完全に相互運用可能です。 これは、両方の言語を使用するコードベースで特に役立ちます。 つまり、回避策を一切必要とせずに、JavaからScala抽象クラスとサブクラスを呼び出すことができます。

抽象クラスは、オブジェクトが何であるかを洗練するためにより多く示されます。 たとえば、抽象クラスを持つことができます動物そして今それを言うのサブクラスです動物。 重要な制限の1つは、 クラスはせいぜい単一の抽象クラスから継承する

抽象クラスは、classキーワードの前に抽象修飾子を付けて定義されます。 さらに 抽象クラスには、完全に定義されたメソッドと抽象メソッドを含めることもできます。

abstract class Animal {

  def heartBeat(): Int = {
    42
  }

  // this is an abstract method that should 
  // be overridden by subclasses
  def eat(): String // returns the sound made while eating
}

3. 特性

抽象クラスと同様に、トレイトは、異なるクラス間で動作を再利用できるようにする継承メカニズムです。 トレイトの最も重要な機能の1つは、クラスが複数のトレイトから継承する可能性があることです。

開発者はそれらをjavaインターフェース比較する傾向がありますが、これらはScalaではこれから説明するようにまったく同じではありません。 また、JavaコードからScalaトレイトを使用しようとすると、いくつかのマイナーな回避策が必要になることがわかります。

トレイトは、特定の動作のメソッドをグループ化するために使用されます。 抽象クラスと同じように、メソッドを実装せずに完全に定義することができます。 特性は、traitキーワードを使用して定義されます。

trait Walker {
  def walk(): Int // returns the number of steps walked
  
  def rest(): Int = {
    0
  }
}

4. 重要な違い

抽象クラスと特性の間には多くの違いがあります。 この記事では、最も重要なことに焦点を当てています。 完全に理解するには、言語仕様と、基盤となるJVM仕様を調べる必要があります。

最初の違いはすでに述べました。クラスは単一の抽象クラスから継承するように制限されていますが、複数の特性から継承できます。

もう1つの重要な違いは、抽象クラスではコンストラクターパラメーターを指定できることです。トレイトでは同じことはできません。 それにもかかわらず、どちらのアプローチでもタイプパラメータを指定できます。

抽象クラスまたは特性をいつ使用するかを決定するためのいくつかのガイドライン:

  • 複数の無関係なクラスで再利用される可能性がある場合は、トレイトとして実装する必要があります。 複雑なクラス階層では、特性を混合することは可能ですが、間に抽象クラスを追加することはできません。
  • それでもわからない場合は、上記を考慮した上で、それを特性にすることから始めましょう。 後でいつでも変更できます。一般に、トレイトを使用すると、より多くのオプションが開かれます。

5. 結論

この記事では、Scalaで継承を使用して動作を再利用するための2つのアプローチ、抽象クラス特性を見ました。 それぞれの使い方を確認し、主な違いを確認しました。