ICT関連の学習備忘録

ICTの学習をアウトプットするワークブックサイト

ICT関連の学習備忘録

2019/09/25:クラスの継承

継承

javaでは、すでに作成したクラスを基にして、新しいクラスを
作成することが出来るようになっており、新しいクラスを作成する事を、
クラスを拡張する(extends)という。
新しいクラスは、既存のクラスのメンバを「受け継ぐ」仕組みになっていて
依存のクラスに新しく必要となる性能や機能(メンバ)をつけたすように、
コードを書いていく事が出来る。
嵐句拡張したクラスが既存のクラスのメンバを受け継ぐことを、
「継承(inheritance)」と呼び、元になる
既存のクラスはスーパークラス(superclass)・親クラス、
新しいクラスはサブクラス(subclass)・子クラスと呼ばれる。
構文
class サブクラス名 extends スーパークラス名
{
サブクラスに追加するメンバ・・・
サブクラスのコンストラクタ(引数リスト)
{
・・・
}
}
//車クラス
class Car	//スーパークラスの宣言
{
	private int num;
	private double gas;
	
	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("車を作成しました。");
	}
	
	public void setCar(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "にしました。");
	}
	
	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
	
}

//レーシングカークラス
class RacingCar extends Car	//サブクラスの宣言
{
	private int course;		//追加するフィールド
	
	public RacingCar()
	{
		course = 0;
		System.out.println("レーシングカーを作成しました。");
	}
	
	public void setCourse(int c)
	{
		course = c;
		System.out.println("コース番号を" + course + "にしました。");
	}
}


class Sample1
{
	public static void main(String[] args)
	{
		RacingCar rccar1 = new RacingCar();
		
		rccar1.setCar(1234,30.2);
		rccar1.setCourse(5);
		
		rccar1.show();
	}
}

java10.html#実行結果
C:\YJSample\11>java Sample1
車を作成しました。
レーシングカーを作成しました。
ナンバーを1234にガソリン量を30.2にしました。
コース番号を5にしました。
車のナンバーは1234です。
ガソリン量は30.2です。

スーパークラスのコンストラクタ

サブクラスのコンストラクタ内の先頭で、特に何も指定しないと
スーパークラスの引数のないコンストラクタが呼び出される事になっている。
呼び出されるコンストラクタを自分で指定する場合、
サブクラスのコンストラクタの先頭で、super()という呼び出しをすることが出来る。
※super()を記述すると、スーパークラスのどのコンストラクタを呼び出すか自分で指定可能。

this()とsuper()
this():そのクラスの別のコンストラクタを呼び出す。
super():そのクラスのスーパークラスのコンストラクタを呼び出す。
//車クラス
class Car	//スーパークラスの宣言
{
	private int num;
	private double gas;
	
	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("車を作成しました。");
	}
	
	public Car(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "の車を作成しました。");
	}
	
	public void setCar(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "にしました。");
	}
	
	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
	
}

//レーシングカークラス
class RacingCar extends Car	//サブクラスの宣言
{
	private int course;		//追加するフィールド
	
	public RacingCar()
	{
		course = 0;
		System.out.println("レーシングカーを作成しました。");
	}
	
	public RacingCar(int n, double g, int c)
	{
		super(n, g);	//スーパークラスの引数2個のコンストラクタが呼び出されるようにする。
		course = c;
		System.out.println("コース番号を" + course + "のレーシングカーを作成しました。");
	}
	public void setCourse(int c)
	{
		course = c;
		System.out.println("コース番号を" + course + "にしました。");
	}
}


class Sample2
{
	public static void main(String[] args)
	{
		RacingCar rccar1 = new RacingCar(1234, 20.5, 5);
	}
}

java10.html#実行結果
C:\YJSample\11>java Sample2
ナンバーを1234にガソリン量を20.5の車を作成しました。java10.html#サブクラスの引数3個のコンストラクタが
コース番号を5のレーシングカーを作成しました。		java10.html#呼び出されるようにする。

メンバへのアクセス

スーパークラスのprivateメンバには、サブクラスからも
アクセスする事が出来ないようになっている。
つまり、サブクラスであるRacingCarクラスにnewShow()等のメソッドを
定義してもCarクラスのprivateメンバであるnumやgasにはアクセスが出来ない。

protectedメンバ:サブクラスから、スーパークラスの
protectedメンバにアクセスする事が出来る。
※javaではprotectedの指定をすると、サブクラスの他、同じパッケージに
属するクラスからもアクセスが出来るようになります。
//車クラス
class Car	//スーパークラスの宣言
{
	//スーパークラスのメンバをprotectedにする。
	protected int num;
	protected double gas;
	
	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("車を作成しました。");
	}
	
	public void setCar(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "にしました。");
	}
	
	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
	
}

//レーシングカークラス
class RacingCar extends Car	//サブクラスの宣言
{
	private int course;		//追加するフィールド
	
	public RacingCar()
	{
		course = 0;
		System.out.println("レーシングカーを作成しました。");
	}
	
	public void setCourse(int c)
	{
		course = c;
		System.out.println("コース番号を" + course + "にしました。");
	}
	
	public void newShow()
	{
		System.out.println("レーシングカーのナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
		System.out.println("コース番号は" + course + "です。");
	}
}


class Sample3
{
	public static void main(String[] args)
	{
		RacingCar rccar1 = new RacingCar();
		
		rccar1.setCourse(2);
		rccar1.setCar(2222,1.11);
		rccar1.newShow();
	}
}

java10.html#実行結果
C:\YJSample\11>java Sample3
車を作成しました。
レーシングカーを作成しました。
コース番号を2にしました。
ナンバーを2222にガソリン量を1.11にしました。
レーシングカーのナンバーは2222です。	java10.html#protectedメンバ
ガソリン量は1.11です。
コース番号は2です。

メソッドのオーバーライド

サブクラスで新しくメソッドを記述するときは、
スーパークラスとまったく同じメソッド名・引数の数・型をもつ
メソッドを定義する事が出来る。
また、メソッド名・引数の数・型がまったく同じである場合は、
サブクラスで新しく定義したメソッドが呼び出される。
サブクラスのメソッドが、スーパークラスのメンバに代わって機能
する事をオーバーライド(overriding)と呼ぶ。
//車クラス
class Car
{
	protected int num;
	protected double gas;
	
	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("車を作成しました。");
	}
	
	public void setCar(int n , double g)
	{
		num = n;
		gas = g;
		System.out.println("ナンバーを" + num + "にガソリン量を" + gas + "にしました。");
	}
	//スーパークラスのshow()メソッド
	public void show()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
}

//レーシングカークラス
class RacingCar extends Car
{
	private int course;
	
	public RacingCar()
	{
		course = 0;
		System.out.println("レーシングカーを作成しました。");
	}
	
	public void setCourse(int c)
	{
		course = c;
		System.out.println("コース番号を" + course + "にしました。");
	}
	//サブクラスのshow()メソッド。
	public void show()
	{
		System.out.println("レーシングカーのナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
		System.out.println("コース番号は" + course + "です。");
	}
}


class Sample4
{
	public static void main(String[] args)
	{
		RacingCar rccar1 = new RacingCar();
		
		rccar1.setCar(2222,1.11);
		rccar1.setCourse(2);
		rccar1.show();	//show()メソッドを呼び出すと・・・
	}
}

java10.html#実行結果
C:\YJSample\11>java Sample4
車を作成しました。
レーシングカーを作成しました。
ナンバーを2222にガソリン量を1.11にしました。
コース番号を2にしました。
レーシングカーのナンバーは2222です。
ガソリン量は1.11です。
コース番号は2です。

スーパークラスの変数でオブジェクトを扱う

今までサブクラスの変数を用意して、オブジェクトを指すようにしていたが、
サブクラスのオブジェクトはスーパークラスの変数で扱うことが出来る
ようになっている。
つまりjavaではオブジェクトを指す変数のクラスに関係なく、
オブジェクト自身のクラスによって、適切なメソッドが呼び出されている。
※スーパークラスの変数を使って、サブクラスのオブジェクトを扱うことが出来る。
class Sample5
{
	public static void main(String[] args)
	{
		//スーパークラスの変数でサブクラスのオブジェクトを扱う。
		Car car1 = new RacingCar();
		
		car1.setCar(2222,1.11);
		car1.show();	//show()メソッドを呼び出すと・・・
	}
}

java10.html#実行結果
C:\YJSample\11>java Sample5
車を作成しました。
レーシングカーを作成しました。
ナンバーを2222にガソリン量を1.11にしました。
レーシングカーのナンバーは2222です。
ガソリン量は1.11です。
コース番号は0です。

オーバーライドの重要性を知る

コードの中では、様々なクラスのオブジェクトを管理しなければ
ならないことがあります。この時、次のように
スーパークラスの配列変数を準備してオブジェクトを扱うことがあります。
配列を利用して呼び出すことで、そのオブジェクトのクラスに対応した処理が
適切に行われている事になる

オーバーライドが行われる事によって、オブジェクトをまとめて扱うことが出来ます。
このように、1つのメソッド名がその状況に応じて色々な働きをする事を、
多様性(ポリモーフィズム:polymorphism)と呼びます。

オーバーライドとオーバーロード
オーバーロード:メソッド名が同じで引数の形式が異なるメソッドを定義する事
オーバーライド:サブクラスで、スーパークラスのメソッド名・引数の形式が
          まったく同じであるメソッドを定義する事
class Sample6
{
	public static void main(String[] args)
	{
		//スーパークラスの配列を準備する。
		Car[] cars = new Car[2];
		
		//スーパークラスのオブジェクトを作成する。
		cars[0] = new Car();
		cars[0].setCar(1234,20.5);
		
		//サブクラスのオブジェクトを作成する。
		cars[1] = new Car();
		cars[1].setCar(4567,30.5);
		
		for(int i=0; i< cars.length; i++){
			cars[i].show();
		}
	}
}

java10.html#実行結果C:\YJSample\11>java Sample6
車を作成しました。
ナンバーを1234にガソリン量を20.5にしました。
車を作成しました。
ナンバーを4567にガソリン量を30.5にしました。
車のナンバーは1234です。
ガソリン量は20.5です。
車のナンバーは4567です。
ガソリン量は30.5です。

スーパークラスのメンバへのアクセス(super.)

サブクラス内でスーパークラスから珪素湯下同じ名前のメソッドを
呼び出す場合や、スーパークラスのフィールドにアクセスする場合には、
サブクラス内で「super.」を付ける事で、スーパークラスのメンバにアクセス出来る。
class RacingCar extends Car
{
	・・・
	public void show()
	{
		//スーパークラス(extendsしているCarクラス)のshow()メソッドを呼び出す。
		super.show();
		System.out.println("コース番号は" + course + "です。");
	}
}
class Car
{
	int x;	//スーパークラスにxがあり・・
	・・・
}

class RacingCar extends Car
{
	int x;	//サブクラスにもxがある。
	・・・
	
	public void show()
	{
		x = 10;			//このxはサブクラスのフィールドの事を指す。。
		super.x = 20;	//このxはスーパークラスのフィールドの事を指す。
	}
}



前のページへ戻る