継承・抽象クラス・インタフェースを理解する

継承は既存クラスの性質を持つ新しいクラスを定義する仕組みです。extendsで親子関係を作り、引き継げるメンバー、追加した状態、親型の参照、抽象クラスとインタフェースの役割を区別します。

この単元で学ぶこと

  • extendsによる単一クラス継承を判定する
  • 継承するメンバーと追加メンバーを追う
  • 具体クラス・抽象クラス・インタフェースを区別する

本文解説

extendsで親を指定 class Parent{int n=3;}class Child extends Parent{}ならChildの実体から継承したnを使えます。親のコードをそのまま貼り付けるのではなく、型として親子関係を持たせます。ChildはParentの一種として扱えます。

単一のクラス継承 class Child extends A,Bは不正です。クラスが直接継承するクラスは一つです。ただしParentがさらにGrandを継承する多段階の関係は作れます。複数の契約を実装するインタフェースとは区別します。

メンバーを追加する 子は親のアクセス可能なメンバーを使い、独自のフィールドやメソッドを追加できます。親n=3と子m=4を持つ実体なら合計7を計算できます。親クラスの実体が自動的に子の追加メンバーを持つわけではありません。

継承されないもの コンストラクタは継承されません。親がParent(int x)しか持たないなら、子は適切にsuper(x)を呼ぶコンストラクタが必要です。またprivateフィールドは子の単純名からアクセスできません。親が公開するメソッドを通じて状態を利用する設計があります。

親型への代入 Parent p=new Child();は子の実体を親として扱う拡大参照変換です。pから利用できるメンバーは宣言型Parentに基づき検査します。Childだけにあるextra()はp.extra()では呼べません。実体を親へ変形する操作ではありません。

継承を禁止するfinal final class Parent{}は継承できません。finalフィールドの再代入禁止、finalメソッドのオーバーライド禁止とは対象が違います。どこにfinalが付いているかを見て制約を判断します。

抽象クラス abstract class Shape{abstract int area();}はareaの実装を子へ委ねます。new Shape()はできません。class Square extends Shape{int area(){return 4;}}のように未実装の抽象メソッドを実装した具体クラスは生成できます。共通の通常メソッドやフィールドを抽象クラスに置くことも可能です。

インタフェースとの接点 interface Named{String name();}は操作の契約です。class User implements Named{public String name(){return "U";}}と実装し、Named n=new User()で使います。単純な抽象インタフェースメソッドはpublicで、実装側もpublicにします。クラス継承のextendsと契約実装のimplementsを使い分けます。

図解

親の契約と子の実装
変数の型と実体の型を分けると利用可能なメンバーと実行先を整理できる。

重要ポイント

  • クラスが直接extendsできるクラスは一つ。
  • コンストラクタとprivateメンバーは継承されない。
  • 子の実体を親型の変数へ代入できる。
  • abstractクラスやinterfaceをそのままnewできない。

間違えやすい点

  • 親のコンストラクタ名で子を生成できると思わない。
  • 子の専用メソッドを親型変数から無条件に呼ばない。
  • implementsの宣言なしに同名メソッドだけで契約実装になると思わない。

用語解説

スーパークラス
extendsで引き継ぐ側の親クラス。
サブクラス
親を拡張して定義する子クラス。
抽象クラス
直接インスタンス生成しないabstract指定のクラス。
インタフェース
実装クラスが提供すべき操作等を定義する参照型。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。