抽象メソッド・クラス(abstract)について

Java言語では処理を記述しないメソッドやそれを持つクラスを定義することができます。

この処理内容を記述しないメソッドを抽象メソッド(abstractメソッド)、抽象メソッドを持つクラスを抽象クラス(abstractクラス)と呼びます。

反対に今までずっとやってきた処理を記載していたクラスやメソッドは具象メソッド、具象クラスを呼びます。

抽象クラスは具象メソッドと抽象メソッドを混在させることができます。

抽象クラスとは

「一部は完成しているけど、全部は決まっていないクラス」です。

  • 実装を持つことができるインターフェースとは違い、具体的な動作を書くことができます。
  • 継承して使う:抽象クラスを継承して、そこに書かれていない部分(抽象メソッド)を埋めます。
  • 単一継承:クラスは1つの抽象クラスしか継承できません。

抽象メソッドとは

「中身が書かれていないメソッド」何をするかは決まっていないけど、「このメソッドは必要ですよ!」とだけ宣言しておくものです。実際に「何をするか」は、子クラスで決めてねという感じ。

  • 中身がない:メソッド名と引数だけがあり、処理内容(コード)はありません。
  • abstract キーワードを使って定義します。
  • 抽象メソッドが含まれるクラスは抽象クラスでなければなりません。
  • 抽象メソッドを持つクラスを継承する場合、そのメソッドをオーバーライドして実装する必要があります

こちらではより具体的に説明をします。

抽象クラスの特徴は以下の通りです。

  • 抽象クラスの宣言時にabstract修飾子を指定する
  • 処理内容が記載された具象メソッドと抽象メソッドを混在できる。
  • 抽象クラス自体はインスタンス化できない。利用する場合は抽象クラスを継承したサブクラスを作成する。
  • 抽象クラスを継承したサブクラスが具象クラスの場合、元となる抽象クラスにある抽象メソッドのオーバーライドは必須である。
  • 抽象クラスを継承したサブクラスが抽象クラスの場合、元となる抽象クラスにある抽象メソッドのオーバーライドは任意である。

抽象メソッドの特徴は以下の通りです。

  • メソッド宣言でabstract修飾子を指定する。
  • アクセス修飾子、戻り値の型、メソッド名、引数リストは、具象メソッドと同様に記述する。
  • 処理を持たないため、メソッド名()の後に{}を記述せず;(セミコロン)で終わる

また、abstractは必ず先頭に記述してください。アクセス修飾子の後になります。

処理がなく、中身がないのが抽象メソッドなので抽象メソッド自体は処理を実行するmainクラスでインスタンス化しても意味がないんですね。(呼び出しても処理が記載されていないため)なので抽象クラスを継承してサブクラスを作り、その抽象クラスをオーバーライドしたクラスをいじる必要があるとのことなんです。

抽象クラスの構文

  • [アクセス修飾子] abstract class クラス名{}

抽象メソッドの構文

  • [アクセス修飾子] abstract 戻り値の型 メソッド名 (引数リスト);

※abstractの位置は先頭、{}は付けない これがポイントです。

例を出します↓↓

例えば、動物を作りたいけど、どんな鳴き声を出すかはまだ決めてない状況を考えましょう。

この抽象クラスのAnimalを継承するクラスでこのsoundメソッドを具体的に実装します。

これを実際に使うと?実際に「犬」と「猫」にその鳴き声を決めてもらうことにしましょう。

dogクラス、catクラスそれぞれextendsでabstractがついた抽象クラスAnimalを継承しています。継承先のクラスで抽象メソッドであるsound();をオーバーライドして、処理を実装しています。

処理を実行するには?mainメソッドで呼び出しましょう。

抽象クラスであるAnimalは処理を持たない為、インスタンス化できません。なので実装するクラス(dogとcat)を作成し、そのクラス(dogとcat)をインスタンス化しています。実際にはコンストラクタの明示的な定義はないので引数なしのデフォルトコンストラクタが作成され呼び出されています。

最後の二行でdogクラスのsoundメソッド、catクラスのsoundメソッドが呼び出され、コンソールには鳴き声が出力される。という流れになりますね。

抽象クラス抽象メソッドの関係は、「抽象クラスが抽象メソッドを持つ入れ物」であるという関係です。簡単に言うと、抽象メソッドは抽象クラスの中にしか存在できない、というルールがあります。

抽象クラスと抽象メソッドの関係を簡単に説明すると

  1. 抽象クラス
    • 「完全に実装されていないクラス」のこと。(中途半端なクラス)
    • 抽象メソッドを1つ以上含むことができます。
    • 抽象メソッド以外にも、普通のメソッド(中身が書かれているメソッド)を持つこともできます。
  2. 抽象メソッド
    • 「中身がないメソッド」で、抽象クラス内で定義されます。
    • 必ずその抽象クラスを継承するクラスで具体的に実装(中身を書くこと)しなければなりません。

例です↓↓

まとめ

  • 抽象クラスは「抽象メソッドを含められるクラス」。
  • 抽象メソッドは「中身がないメソッド」で、抽象クラスの中でしか定義できない
  • 抽象クラスを継承する子クラスは、抽象メソッドを具体的に実装する義務があります。

つまり、抽象クラスが「設計図のベース」で、抽象メソッドが「詳細な設計は後で決める部分」という役割です。

コメント

タイトルとURLをコピーしました