この章で説明する「継承」という機能は、オブジェクト指向の中でも非常に重要な位置を占めるものです。
実際、ここから最後まではこの「継承」という機能を中心に解説しますので、この章はしっかり理解しましょう。
クラスを継承する
クラスには「継承」という、「あるクラスの機能を持ったクラスを作る」機能があります。
この継承を使うことで、コピペをしなくてもクラスを「複製」することができます。
/**
* 普通のクラス。
*/
class SuperClass
{
// int型変数のdataフィールドです。
int data;
/**
* フィールドを出力するメソッドです。
*/
void printData()
{
System.out.println( data );
}
}
/**
* SuperClassクラスから継承した、サブクラス。
*/
class SubClass extends SuperClass
{
// 中身は空。
}
/**
* 実行用クラス。このクラスを実行してください。
*/
class SubClassRunner
{
public static void main( String[] args )
{
// インスタンスを1つ作り数値を入れます。
SubClass ref = new SubClass();
// フィールドに値を入れて出力します。
ref.data = 100;
ref.printData();
// 出力結果:
// 100
}
}
// SubClassRunner.java /** * 普通のクラス。 */ class SuperClass { // int型変数のdataフィールドです。 int data; /** * フィールドを出力するメソッドです。 */ void printData() { System.out.println( data ); } } /** * SuperClassクラスから継承した、サブクラス。 */ class SubClass extends SuperClass { // 中身は空。 } /** * 実行用クラス。このクラスを実行してください。 */ class SubClassRunner { public static void main( String[] args ) { // インスタンスを1つ作り数値を入れます。 SubClass ref = new SubClass(); // フィールドに値を入れて出力します。 ref.data = 100; ref.printData(); // 出力結果: // 100 } }
まず、フツーのクラス、SuperClassクラスがあります。
* 普通のクラス。
*/
class SuperClass
{
// int型変数のdataフィールドです。
int data;
/**
* フィールドを出力するメソッドです。
*/
void printData()
{
System.out.println( data );
}
}
/** * 普通のクラス。 */ class SuperClass { // int型変数のdataフィールドです。 int data; /** * フィールドを出力するメソッドです。 */ void printData() { System.out.println( data ); } }
このクラスは何の変哲もない普通のクラスです。
このプログラムでは、SuperClassクラスをそのまま使うのではなく、SuperClassクラスを継承して、SubClassクラスという新しいクラスを作り、それを使います。
* SuperClassクラスから継承した、サブクラス。
*/
class SubClass extends SuperClass
{
// 中身は空。
}
/** * SuperClassクラスから継承した、サブクラス。 */ class SubClass extends SuperClass { // 中身は空。 }
「extends」という新しいキーワードを使用していますね。
「class A extends B」とすると、AクラスにBクラスの機能を持たせることができます。
これを「継承」(けいしょう)と言います。
「AクラスはBクラスを継承している」といった言い方をします。この例なら「SubClassクラスはSuperClassクラスを継承している」となります。
また、Bクラス(元々機能を持っていた側)を「スーパークラス」、Aクラス(新しく作ったクラス)を「サブクラス」と言います。この例ならSuperClassクラスがスーパークラス、SubClassクラスがサブクラスとなります。
サブクラスのインスタンスを作ると、その中にスーパークラスのインスタンスが作られます。
SubClass ref = new SubClass();
// インスタンスを1つ作り数値を入れます。 SubClass ref = new SubClass();
インスタンスの作り方はこれまでと変わりません。普通にnewで作ります。
サブクラスのインスタンスを作ると、自動的にその中にスーパークラスのインスタンスが作られます。
これが「サブクラスはスーパークラスの機能を持つ」ということです。
サブクラスのインスタンスはスーパークラスのインスタンスを持っているので、その中にあるフィールドやメソッドも使うことができるというわけです。
スーパークラスのフィールドやメソッドは、そのまま使うことができます。
ref.data = 100;
ref.printData();
// 出力結果:
// 100
// フィールドに値を入れて出力します。 ref.data = 100; ref.printData(); // 出力結果: // 100
dataフィールド・printData()メソッドは両方ともSuperClassクラスのフィールド・メソッドです。
でも使っているのはSubClassクラスです。
サブクラスを通してスーパークラスのフィールド・メソッドを特別なことをしなくてもそのまま使うことができるため、このようにスーパークラスを使っている時のようにフィールド・メソッドを使用することができるわけです。
ref変数が指しているインスタンスはSubClassクラスのインスタンスですが、その中にSuperClassクラスのインスタンスが入っていて、その中にdataフィールド・printData()メソッドが入っています。
スーパークラスのインスタンスをサブクラスのインスタンスが覆っていますが、外から使う時には、中にあるスーパークラスのフィールド・メソッドを直接使うことができます。
そのため、使われかただけを見るとまるでサブクラスがスーパークラスをそのままコピーしたように見えます。
継承を使うことで、このように「まるでコピペしたようなクラス」を作ることができます。これが継承の第1のメリットになります。