継承・抽象クラス・インタフェースのコードトレース

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

この単元で学ぶこと

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

本文解説

親の状態と子の状態 Parentがn、Childがmを持つなら一つのChild実体に両方の状態があります。new Parent()という別の実体も作れば、そのnとは独立です。親子クラスという型の関係が、すべての実体の状態共有を意味するわけではありません。

親から子への代入 Child c=new Parent()は不正です。親の実体が常に子の機能を持つとは限りません。Parent p=new Child()のような逆方向は安全な拡大です。型関係の矢印を両方向同じに扱わないようにします。

抽象宣言の継承 抽象メソッドを実装しないサブクラスは自分もabstractでなければなりません。abstractな中間クラスを経由し、最後の具体クラスで実装する構造は可能です。newできるのは未実装メソッドを残さない具体クラスです。

抽象クラス内の通常メソッド abstract class Base{int twice(){return value()*2;}abstract int value();}の通常メソッドは利用できます。子がvalueを3で実装するとtwiceは6です。抽象クラスはすべてのメソッドが抽象である必要はありません。

インタフェースの直接生成 new Named()は不正です。ここでは匿名クラスを使わず、implementsした通常クラスを生成します。同じnameメソッドがあるだけのクラスを、implements宣言なしでNamed変数へ代入することもできません。Javaは明示した型関係を使います。

実装メソッドの公開範囲 interface Named{String name();}のnameは暗黙にpublic abstractです。実装側がString name()のままだと公開範囲を狭めるため不正です。public String name()と宣言して契約を満たします。

複数インタフェース class Item implements Named,Valuedのように複数の契約を実装できます。さらにextends Baseと組み合わせる場合はextendsを先に、implementsを後に書きます。複数のクラスをextendsすることとは違います。

インタフェースの継承 interface Detailed extends Namedは親の操作契約も持ちます。Detailedを実装する具体クラスは親のnameも実装します。インタフェース同士はextends、クラスからインタフェースへはimplementsという区別を守ります。

図解

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

重要ポイント

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

間違えやすい点

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

用語解説

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

関連教材

参考資料

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

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