継承は、インヘリタンスとも呼ばれます。既に用意されているオブジェクトを基に、機能などを追加して新たなオブジェクトを作ることができる機能です。
これから、Busクラスを作成してみましょう。バスは、人を乗せて運ぶことができますが、車と同じように進んだり、止まったりすることができます。つまり、Carクラスのような機能を持っています。「バスは車である」ということができます。このような関係を「is-a」の関係といいます(Bus is a Car)。
このような場合、BusクラスはCarクラスの機能等を引き継いで作成することができます。Carクラスを継承してBusクラスを作ることができます。このようにすることで、Busにしかない属性、機能を記述すればよくなります。つまり、CarクラスとBusクラスの差分を記述するわけです。
継承において、もとになるクラスをスーパークラスや基底クラスといい、それをもとに新しく作成するクラスをサブクラスや派生クラスといいます。
クラス継承の書式 |
---|
class サブクラス名 extends スーパークラス名{ 各種定義… } |
継承の指定をした後、スーパークラスにはないフィールドやメソッドを追加や修正する記述をします。
○ ファイル
次のようにファイルを作成してください。
ファイル名 | Bus.java |
---|
○ プログラム
Busクラスを追加して、次のように記述してください。
○ クラス図
○ 解説
1行目でCarクラスを継承しています。これにより、Carクラスが持っているspeedUpメソッド、speedDownメソッドが使えるようになります。
3行目のフィールド変数は売上金額を扱います。乗客が乗車するたびに加算されていきます。このフィールドはprivate修飾子がついているので、設定はクラス内部からしかできないようになっています。値を取得するには54行目から定義されているgetSalesAmount()メソッドを利用します。4行目のフィールド変数は現在の乗客数を扱います。今回は50人まで乗せられるようにプログラムで制御しています。このフィールドも設定はクラス内部からしかできないようになっています。取得するには58行目から定義されているgetPassengerNumber()メソッドを利用します。
7~9行目ではコンストラクタを定義しています。このコンストラクタは引数なしで呼ばれると、オーバーロードしているガソリン量を受け取るコンストラクタを呼び出します。11~15行目では、ガソリン量を受け取るコンストラクタを定義しています。12行目はスーパークラスのコンストラクタを呼び出しています。「super」キーワードは、スーパークラスを表します。ここでのsuperキーワードはCarクラスを表します。
19~34行目は乗車するメソッドです。このメソッドは運賃を受け取り、乗車処理をします。その際、バスが走っていたり、乗客数が満員になっていたりすると乗車できないようにしています。いずれにも当てはまらない場合は、受け取った運賃を売上金額フィールドに加算し、乗客数フィールドを1人分増やします。
37~51行目は降車するメソッドです。バスが走っていたり、乗客がいない場合は降車できないようにしています。いずれにも当てはまらない場合は、乗客数フィールドを1人分減らします。
○ ファイル
Run1.javaをコピーして、次のようにファイルを作成してください。
ファイル名 | Run2.java |
---|
○ プログラム
次のようにプログラムを記述してください。
○ 解説
14行目でBusオブジェクトを生成しています。BusオブジェクトはCarクラスを継承しているので今まで通り加速したり、減速したりできます。46行目では乗車メソッドを呼び出しています。戻り値がnullでない場合はエラーメッセージが返って来ているので、コンソールに表示しています。55行目では降車メソッドを呼び出しています。このメソッドは乗車メソッドと同様にエラーメッセージかnullが返ってくるのでそれに応じた処理をしています。
今回はCarクラスを基にBusクラスを作成しました。BusクラスはCarクラスを継承しているので、Carクラスのメンバを記述しなくても使用することができます。ただし、privateになっているメンバは、継承したクラスでも直接アクセスすることができません。「protected」にすれば、直接操作できます。「protected」は、継承関係であればアクセスできますが、外部クラスからはアクセスすることができません。
Javaでは、サブクラスは1つのクラスから継承することができます。複数のクラスから継承させることはできません。(多重継承の禁止)
Busクラスのインスタンスを生成するときにBusクラスのコンストラクタを呼び出します。すると、初めにスーパークラスであるCarクラスのコンストラクタを呼び出します。サブクラスのコンストラクタでスーパークラスのコンストラクタの呼び出しが特に記述されていない場合、スーパークラスのデフォルトコンストラクタが呼び出されます。もし、スーパークラスで引数を持つコンストラクタが定義されていると、デフォルトコンストラクタは仮定されないので、サブクラスでスーパークラスのコンストラクタの呼び出しを記述しなければなりません。