ICT関連の学習備忘録

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

ICT関連の学習備忘録

2019/09/26:抽象クラス・インターフェイス

抽象クラス(abstract)

abstractという修飾詞が付いているクラスを抽象クラス(abstract class)と言う。
この抽象クラスは、「オブジェクトを作成することが出来ない」という特徴と
「処理内容が定義されていないメソッドを持っている」と言う特徴をもっている。
抽象クラスは変数を持てる。
構文
abstract class クラス名
{
フィールドの宣言;
abstract 戻り値の型 メソッド名(引数リスト);
・・・
}
抽象クラスから継承した抽象メソッドの内容を
サブクラスできちんと定義してオーバーライドする(実装)
//のりものクラス
abstract class Vehicle	//抽象クラス
{
	protected int speed;
	public void setSpeed(int s)
	{
		speed = s;
		System.out.println("速度を" + speed + "にしました。");
	}
	abstract void show();	//抽象メソッドshow()
}
//車クラス
class Car extends Vehicle	//抽象クラスを拡張
{
	private int num;
	private double gas;
	
	public Car(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "ガソリン量" +
			gas + " の車を作成しました。");
	}
	public void show()
	{
		//show()メソッドの処理を定義
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
		System.out.println("速度は" + speed + "です。");
	}
}

//飛行機クラス
class Plane extends Vehicle		//抽象クラスを拡張
{
	private int flight;
	
	public Plane(int f)
	{
		flight = f;
		System.out.println("便" + flight + "の飛行機を作成しました。");
	}
	public void show()
	{
		//show()メソッドの処理を定義
		System.out.println("飛行機の便は" + flight + "です。");
		System.out.println("速度は" + speed + "です。");
	}
}

class Sample1
{
	public static void main(String[] args)
	{
		Vehicle[] vc = new Vehicle[2];	//抽象クラスの配列を準備。
		
		vc[0] = new Car(1234,20.5);	//1番目のオブジェクトはCarクラス
		vc[0].setSpeed(60);
		
		vc[1] = new Plane(232);	//2番目のオブジェクトはPlaneクラス
		vc[1].setSpeed(500);
		
		for(int i=0; i<vc.length; i++){
			vc[i].show();	//show()メソッドの呼び出し。
		}
	}
}

java11.html#実行結果
C:\YJSample\12>java Sample4
ナンバーを1234ガソリン量20.5 の車を作成しました。
車のナンバーは1234です。
ガソリン量は20.5です。java11.html#オブジェクトのクラスに対応した、
車の材料は鉄です。    java11.html#show()メソッドが呼び出される。

オブジェクトのクラスを調べる(instanceof)

instanceof演算子(instanceof operator)を使うと、オブジェクトのクラスを
調べる事が出来る。
//Sample1部分省略

class Sample2
{
	public static void main(String[] args)
	{
		Vehicle[] vc = new Vehicle[2];	//抽象クラスの配列を準備。
		
		vc[0] = new Car(1234,20.5);	//1番目のオブジェクトはCarクラス
		vc[0].setSpeed(60);
		
		vc[1] = new Plane(232);	//2番目のオブジェクトはPlaneクラス
		vc[1].setSpeed(500);
		
		for(int i=0; i<vc.length; i++){
			if(vc[i] instanceof Car){	//オブジェクトがCarクラスかどうか調べる。
				System.out.println((i+1) + "番目のオブジェクトはCarです。。");
			}else{
				System.out.println((i+1) + "番目のオブジェクトはCarクラスではありません。");
			}
		}
	}
}

java11.html#実行結果
C:\YJSample\12>java Sample2
ナンバーを1234ガソリン量20.5 の車を作成しました。
速度を60にしました。
便232の飛行機を作成しました。
速度を500にしました。
1番目のオブジェクトはCarです。。
2番目のオブジェクトはCarクラスではありません。

インターフェイス(interface)

抽象クラスと同じような仕組みを、インターフェイス
と言うものを使って表すことが出来る。
インターフェイスは変数は持てず、定数は持てる。
構文
interface インターフェイス名
{
型名 フィールド名 = 式;
戻り値の型 メソッド名();
}
※フィールドは必ず初期化する。メソッドの処理は定義しない。

インターフェイスのメンバには何も修飾詞を付けなくても、
フィールドには「public static final」、
メソッドには「abstract」という修飾詞を付けている事と同義で、
インターフェイスのフィールドは定数、
メソッドは抽象メソッドとなっている
//のりものインターフェイス
interface iVehicle	//インターフェイスを宣言
{
	void show();	//abstractが無くても、インターフェイスでは抽象メソッドになる。
}
//車クラス
class Car implements iVehicle	//インターフェイスを実装(implements)する。
{
	//フィールド
	private int num;
	private double gas;
	//コンストラクタ
	public Car(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "ガソリン量" +
			gas + " の車を作成しました。");
	}
	public void show()
	{
		//抽象メソッド”show()メソッド”の処理を定義
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
}

//飛行機クラス
class Plane implements iVehicle		//インターフェイスを実装
{
	private int flight;
	
	public Plane(int f)
	{
		flight = f;
		System.out.println("便" + flight + "の飛行機を作成しました。");
	}
	public void show()
	{
		//抽象メソッド”show()メソッド”の処理を定義
		System.out.println("飛行機の便は" + flight + "です。");
	}
}


class Sample3
{
	public static void main(String[] args)
	{
		iVehicle[] ivc = new iVehicle[2];	//インターフェイスの配列を準備。
		
		ivc[0] = new Car(1234,20.5);	//1番目のオブジェクトはCarクラス
		
		ivc[1] = new Plane(232);	//2番目のオブジェクトはPlaneクラス

		for(int i=0; i<ivc.length; i++){
			ivc[i].show();
		}
	}
}

java11.html#実行結果
C:\YJSample\12>java Sample3
ナンバーを1234ガソリン量20.5 の車を作成しました。
便232の飛行機を作成しました。
車のナンバーは1234です。
ガソリン量は20.5です。
飛行機の便は232です。

複数のインターフェイスを実装(多重継承)

javaでは2つ以上のスーパークラスを持つサブクラスを認めていないが、
クラスやインターフェイスを組み合わせる事で多重継承の仕組みを
一部実現することが出来る。
※スーパークラス1+スーパークラス2→サブクラスで継承は出来ない。
クラスは、複数のインターフェイスを実装するクラスを宣言出来ます。
構文
class クラス名 implements インターフェイス名1,インターフェイス名2,・・・
{
・・・
}
//のりものインターフェイス
interface iVehicle	//インターフェイスを宣言
{
	void vShow();	//abstractが無くても、インターフェイスでは抽象メソッドになる。
}

//材料インターフェイス
interface iMaterial
{
	void mShow();	//iMaterialの抽象メソッド
}
//車クラス
class Car implements iVehicle, iMaterial	//2つ以上のインターフェイスを実装(implements)する。
{
	//フィールド
	private int num;
	private double gas;
	//コンストラクタ
	public Car(int n , double g)
	{
		num = n ;
		gas = g;
		System.out.println("ナンバーを" + num + "ガソリン量" +
			gas + " の車を作成しました。");
	}
	//iVehicleのメソッドを定義する。
	public void vShow()
	{
		System.out.println("車のナンバーは" + num + "です。");
		System.out.println("ガソリン量は" + gas + "です。");
	}
	//mVehicleのメソッドを定義する。
	public void mShow()
	{
		System.out.print("車の材料は鉄です。");
	}
}

class Sample4
{
	public static void main(String[] args)
	{
		Car car1 = new Car(1234,20.5);
		car1.vShow();
		car1.mShow();
	}
}

java11.html#実行結果
C:\YJSample\12>java Sample4
ナンバーを1234ガソリン量20.5 の車を作成しました。
車のナンバーは1234です。
ガソリン量は20.5です。
車の材料は鉄です。

インターフェイスの拡張

インターフェイスの応用方法として、インターフェイスはクラスと同様に
拡張して新しいインターフェイスを宣言する事が出来ます。
拡張されるほうをスーパーインターフェイス(superinter-face)、
拡張した方をサブインターフェイス(subinterface)といいます。
インターフェイスの拡張にはextendsを使用する。
構文
interface サブインターフェイス名 extends スーパーインターフェイス名1,
スーパーインターフェイス名2,・・・
{
・・・
}

スーパーインターフェイスを拡張して、サブインターフェイスを宣言する事が出来る。
インターフェイスの拡張には「extends」を使うが、これらのインターフェイスをクラス
で実装すると言う場合には、「implements」を使用する。
もし、iVehicleインターフェイスがiMovableインターフェイスを拡張した
サブインターフェイスであった場合、iVehicleインターフェイスを実装する
Carクラスでは、iMovebleインターフェイスのメソッドも定義する必要がある。
//Xインターフェイス
interface X
{
	void methodX();	//Xの抽象メソッド
}

//Yインターフェイス
interface Y
{
	void methodY();	//Yの抽象メソッド
}

//Subインターフェイス
interface Sub extends X,Y
{
	void methodZ();	//Subの抽象メソッド
}


//Bクラス
class B
{
	public static void methodB()
	{
		System.out.println("Bクラス:\n\tメソッドB");
	}
}

//Aクラス
class A extends B implements Sub	//XとYのインターフェイスを実装(implements)する。
{
	public static void methodA()
	{
		System.out.println("Aクラス:\n\tメソッドA");
	}
	//methodXメソッドを定義する。
	public void methodX()
	{
		System.out.println("Xインターフェイス:\n\tメソッドY");
	}
	//methodYのメソッドを定義する。
	public void methodY()
	{
		System.out.println("Yインターフェイス:\n\tメソッドY");
	}
	//methodZのメソッドを定義する
	public void methodZ()
	{
		System.out.println("Subインターフェイス:\n\tメソッドZ");
	}
}

class Sample5 extends B
{
	public static void main(String[] args)
	{
		A outA = new A();
		outA.methodA();
		outA.methodB();
		outA.methodX();
		outA.methodY();
		outA.methodZ();
	}
}

java11.html#実行結果
C:\YJSample\12>java Sample5
Aクラス:
        メソッドA
Bクラス:
        メソッドB
Xインターフェイス:
        メソッドY
Yインターフェイス:
        メソッドY
Subインターフェイス:
        メソッドZ



前のページへ戻る