「抽象」って、そもそもどういう意味?
なんとなくは、理解できるけど上手く説明できない人も多い
本題に入る前に「抽象」について知っておきましょう!
抽象とは
Javaの抽象クラスは、
オブジェクト指向プログラミングにおいて、関連するクラスに共通の機能やデータ構造を提供するための仕組みです!
抽象クラスの定義
抽象クラスは、Javaプログラムにおいて、他のクラスに基本機能を提供するために作成される特殊なクラスです。
抽象クラスは、直接インスタンス化されず、継承によって実装されることが前提となっています。抽象クラスはabstractキーワードを使って定義されます。
abstractキーワードがあることで、そのクラスが抽象クラスであることを示し、インスタンス化されることを防ぎます。
abstract class AbstractClassName {
// ...
}
抽象クラスの特徴
抽象クラスは以下のような特徴を持っています!
- 抽象メソッドと具象メソッドを持つことができます。
- フィールドを持つことができます。
- インスタンス化されることはなく、サブクラスを通じて具象化されます。
- Javaでは、クラスは一つの抽象クラスしか継承できません。
- インターフェースと使い分けることで、再利用性や拡張性が向上します。
抽象メソッドと具象メソッドを持つことができます。
抽象メソッド
抽象メソッドは、実装がなく、メソッドのシグネチャのみを定義しています。抽象メソッドは、継承したサブクラスで実装が必須です。抽象メソッドは、abstractキーワードを使って定義されます。
public abstract void methodName();
具象メソッド
具象メソッドは、実装が与えられた通常のメソッドです。抽象クラスでは、具象メソッドを通して、サブクラスに共通の機能を提供できます。具象メソッドは、サブクラスでオーバーライドされることもあります。
public void methodName() { // メソッドの実装 }
フィールドを持つことができる
フィールド:抽象クラスは、フィールドを持つことができます。フィールドは、サブクラスに共通のデータを格納します。フィールドのアクセス修飾子によって、サブクラスからのアクセス範囲が決まります(private、 protected、 public)。
protected String fieldName;
インスタンス化されることはなく、サブクラスを通じて具象化されます
インスタンス化の制約
抽象クラスはインスタンス化できません。サブクラスを通して具象化されることを期待しています。この制約により、抽象クラスを使って関連するクラスの共通点を抽出し、再利用性を高めることができます。
Javaでは、クラスは一つの抽象クラスしか継承できません
継承の制約
Javaでは、クラスは一つの抽象クラスしか継承できません。この制約により、多重継承に関する問題(ダイヤモンド問題など)を回避しています。複数のクラスからメソッドやフィールドを継承する必要がある場合は、インターフェースを使用することが推奨されます。
インターフェースと使い分けることで、再利用性や拡張性が向上します
インターフェースとの関係
抽象クラスとインターフェースは、機能や振る舞いを共有するクラスを設計する際に使用されますが、使い分けが重要です。抽象クラスは共通の機能やデータ構造を提供し、インターフェースは共通の振る舞いを定義します。また、Javaではクラスは複数のインターフェースを実装できますが、一つの抽象クラスしか継承できません。
抽象クラスの実装例
以下に、抽象クラスを使用した簡単な実装例を示します。
// 抽象クラス Animal abstract class Animal { private String name; public Animal(String name) { this.name = name; } // 抽象メソッド public abstract void sound(); public String getName() { return name; } } // Cat クラスは Animal を継承 class Cat extends Animal { public Cat(String name) { super(name); } @Override public void sound() { System.out.println("Meow!"); } } // Dog クラスは Animal を継承 class Dog extends Animal { public Dog(String name) { super(name); } @Override public void sound() { System.out.println("Woof!"); } } // 実行クラス public class Main { public static void main(String[] args) { Cat cat = new Cat("Misty"); Dog dog = new Dog("Rex"); System.out.println(cat.getName()); cat.sound(); System.out.println(dog.getName()); dog.sound(); } }
実行結果
Misty Meow! Rex Woof!
この実行結果は、まずCat
クラスのインスタンスcat
の名前(Misty
)が表示され、その後にcat
の鳴き声(Meow!
)が表示されます。次に、Dog
クラスのインスタンスdog
の名前(Rex
)が表示され、その後にdog
の鳴き声(Woof!
)が表示されます。このコード例では、抽象クラスAnimal
を継承することで、Cat
クラスとDog
クラスが共通の機能(getName()
メソッド)を利用し、またそれぞれ独自の鳴き声を提供(sound()
メソッドのオーバーライド)しています。
抽象クラスを効果的に使う
抽象クラスを効果的に使用するためには、以下に従ってください。
- 関連するクラス間で共通の機能やデータ構造がある場合に抽象クラスを使用し、コードの再利用性を向上させましょう!
- 抽象クラスのメソッドは、そのクラスの責任範囲に適したものに限定し、他のクラスからアクセスする必要がないメソッドやフィールドは適切なアクセス修飾子を使用して制限しましょう!
- 抽象クラスでは、共通の初期化処理が必要な場合、コンストラクタを使用して実装しましょう!
- クラスが複数の機能を持つ場合は、インターフェースを使用して柔軟な設計を実現しましょう!
- サブクラスが抽象クラスから継承される機能やデータ構造を適切にオーバーライドし、その責任範囲に沿った実装を提供しましょう!
まとめ
Javaの抽象クラスは、関連するクラスに共通の機能やデータ構造を提供するための強力な仕組みです。適切な使い分けと設計を行うことで、コードの再利用性や拡張性が向上し、高品質なソフトウェア開発が可能になります。
この記事を参考に、抽象クラスを効果的に活用して、より良いJavaプログラムを開発しましょう!
コメント