継承とポリモーフィズム
Scalaにおける継承、抽象クラス、ポリモーフィズムなどのオブジェクト指向の原則を学びます。
「継承とポリモーフィズム」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン2/2です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全2レッスンが含まれています。
継承とは
継承は、オブジェクト指向プログラミング(OOP)の基本概念です。新しい class が既存の class からプロパティや振る舞い(メソッド)を引き継げるようにします。
「親子」関係として考えると分かりやすいでしょう。「子」class(サブクラス)は「親」class(スーパークラス)のコードを再利用できるため、時間を節約し、一貫性を保てます。
- コードの再利用を促進します。
- 「is-a」関係(例:Dog is an Animal)を確立します。
- コードを階層構造に整理しやすくします。
最初の基底 class
シンプルな Animal class を定義してみましょう。これは基底 class であり、スーパークラスまたは親 class とも呼ばれます。「話す」という基本的な振る舞いを持ちます。
コードを実行して、汎用的な動物が動作する様子を確認しましょう。
class Animal {
val name: String = "Generic Animal"
def speak(): Unit = {
println(s"$name makes a sound.")
}
}
object Main {
def main(args: Array[String]): Unit = {
val myAnimal = new Animal()
myAnimal.speak()
}
}`extends` による拡張
それでは、より具体的な動物である Dog を作成しましょう。Dog is an Animal なので、extends キーワードを使って Animal class を継承できます。
また、speak メソッドをオーバーライドして、Dog 独自の鳴き声を定義できます。override キーワードに注目してください。
class Animal {
val name: String = "Generic Animal"
def speak(): Unit = {
println(s"$name makes a sound.")
}
}
class Dog extends Animal {
override val name: String = "Dog"
override def speak(): Unit = {
println(s"$name barks!")
}
}
object Main {
def main(args: Array[String]): Unit = {
val myAnimal = new Animal()
val myDog = new Dog()
myAnimal.speak() // Generic Animal makes a sound.
myDog.speak() // Dog barks!
}
}`override` の力
override キーワードは、Scala で次のような理由から重要です。
- 明確さ:このメソッドまたはフィールドがスーパークラスのメンバーを置き換えることを、他の開発者に明示できます。
- 安全性:既存のメンバーを実際にオーバーライドしているかをコンパイラーが確認します。タイプミスをした場合やスーパークラスのメソッドが変更された場合は、コンパイラーが知らせてくれます。
- 意図:継承した振る舞いを特化または変更する意図を明確に示せます。
継承したメンバーを再定義するときは、必ず override を使ってください。
ポリモーフィズム:多様な形
ポリモーフィズムは「多様な形」を意味します。OOP では、異なる class のオブジェクトを共通のスーパークラスのオブジェクトとして扱えるようにします。
つまり、Animal 型の変数に Dog オブジェクト、Cat オブジェクト、または Animal のその他のサブクラスを格納できます。その変数のメソッドを呼び出すと、実際のオブジェクトの型に対応するメソッドが実行されます。
- 柔軟で拡張しやすいコードを実現します。
- 異なるデータ型に対して単一のインターフェースを使えるようにします。
- メソッドのオーバーライドによって実現されます。
ポリモーフィズムの実践
ポリモーフィズムがどのように動作するか見てみましょう。Dog に似た Cat class を作成します。その後、共通のスーパータイプである Animal のリストに異なる種類の動物を入れ、それぞれの speak メソッドを呼び出します。
リスト内ではすべて Animal 型として扱われているにもかかわらず、それぞれの動物が独自の方法で鳴くことに注目してください。
class Animal {
val name: String = "Generic Animal"
def speak(): Unit = {
println(s"$name makes a sound.")
}
}
class Dog extends Animal {
override val name: String = "Dog"
override def speak(): Unit = {
println(s"$name barks!")
}
}
class Cat extends Animal {
override val name: String = "Cat"
override def speak(): Unit = {
println(s"$name meows!")
}
}
object Main {
def main(args: Array[String]): Unit = {
val animals: List[Animal] = List(
new Animal(),
new Dog(),
new Cat()
)
animals.foreach(_.speak())
}
}abstract class の導入
共通のインターフェースを定義しつつ、一部のメンバーについて完全な実装を提供しない基底 class が必要になることがあります。そのような場合にabstract classを使います。
abstract class には次の特徴があります。
- 直接インスタンス化できません(abstract class のオブジェクトは作成できません)。
- abstract メソッド(実装のないメソッド)と具象メソッド(実装のあるメソッド)の両方を含められます。
- サブクラスが完成させる設計図として機能します。
abstract な設計図の作成
abstract class Shape を定義してみましょう。すべての図形には面積がありますが、その計算式は図形の種類(円、長方形など)によって異なります。
そこで、area をabstract メソッドとして宣言します。本文(= { ... })がないことに注目してください。実装はサブクラスが提供します。
abstract class Shape {
def area: Double // Abstract method, no implementation
def describe(): Unit = {
println("This is a geometric shape.")
}
}
// You cannot do: new Shape() - it's abstract!
object Main {
def main(args: Array[String]): Unit = {
println("Abstract class Shape defined.")
println("Cannot instantiate Shape directly.")
}
}具象実装
次に、abstract class Shape を拡張する Circle や Rectangle などの具象サブクラスを作成しましょう。これらのサブクラスは、abstract な area メソッドを必ず実装する必要があります。
また、Shape から具象メソッドである describe() を継承します。
abstract class Shape {
def area: Double
def describe(): Unit = {
println("This is a geometric shape.")
}
}
class Circle(radius: Double) extends Shape {
override def area: Double = math.Pi * radius * radius
}
class Rectangle(width: Double, height: Double) extends Shape {
override def area: Double = width * height
}
object Main {
def main(args: Array[String]): Unit = {
val circle = new Circle(5)
val rectangle = new Rectangle(4, 6)
println(s"Circle area: ${circle.area}")
circle.describe()
println(s"Rectangle area: ${rectangle.area}")
rectangle.describe()
}
}継承とポリモーフィズムのチェック
Scala の継承とポリモーフィズムについて、次の文のうち正しいものはどれですか。
まとめ:継承とポリモーフィズム
よくできました。このレッスンでは、Scala の OOP における主要な概念を学びました。
- 継承:サブクラスがコードを再利用し、
extendsを使ってスーパークラスとの「is-a」関係を定義する仕組みです。 overrideキーワード:継承したメソッドやフィールドを明示的に再定義するために不可欠で、型安全性と明確さを確保します。- ポリモーフィズム:異なるサブクラスのオブジェクトを共通のスーパークラスのオブジェクトとして扱う機能で、柔軟で拡張しやすいコードを実現します。
- abstract class:直接インスタンス化できない設計図であり、共通のインターフェースや、サブクラスが実装すべき abstract メンバーを定義するために使います。
これらの概念は、構造が整った保守しやすい Scala アプリケーションを構築するうえで非常に重要です。
AI チューターと学ぶ Scala — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 39
- レッスン
- 143
よくある質問
「継承とポリモーフィズム」レッスンは無料ですか?
はい。「継承とポリモーフィズム」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全2レッスンが含まれています。
「継承とポリモーフィズム」で何を学びますか?
Scalaにおける継承、抽象クラス、ポリモーフィズムなどのオブジェクト指向の原則を学びます。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/2です。
「継承とポリモーフィズム」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?
はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- クラス、オブジェクト、パッケージ
- 継承とポリモーフィズム