💡

Java クラスの継承, 抽象クラスと抽象メソッド(abstract), オーバーライド, super

2024/12/10に公開

Java

クラスの継承

・各クラスで同じフィールドやメソッドを定義してしまう場合が生じ得るため、クラスの継承を活用しないでクラスを作成するのは、オブジェクト指向として適切ではない。
・クラスの継承を活用し継承元のフィールドやメソッドを利用すれば、すっきりしたクラスになる。
・トラクタは継承されないので、使うときには注意が必要。コンストラクタとは、クラスがインスタンス化されるときに一度だけ呼び出されるメソッド。

  • クラスの継承で、継承元のクラスのことを 親クラス(スーパークラス) と呼び、継承先のクラスのことを 子クラス(サブクラス) と呼ぶ。
  • クラスの継承とは、親クラス内のフィールドやメソッドを子クラスが継承して使うこと。
  • クラスの継承をコードで書くときは、以下の書式で書く。
子クラス extends 親クラス

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

・子クラスで親クラスのメソッドを上書きすることができる。
・オーバーライドで上書きできるのは引数名と処理だけ。メソッドの名前と戻り値の型と、引数の数や引数の型は親クラスのメソッドと同じにする必要がある。

super

・super は、親クラスのコンストラクタを呼び出すことができる。
・private では親クラスの変数に子クラスでもアクセスできないので、子クラスでもアクセスしたい場合はその親クラスには "protected" を使う。
・アクセス修飾子なしは、自分のクラスと同じパッケージからアクセスできる。

抽象クラスと抽象メソッド(abstract)

  • 抽象メソッドはメソッドの定義の前に "abstract" を付ける。
  • 抽象クラスとは、抽象メソッドの定義を含むクラス。
    * 抽象メソッドの具体的な処理は抽象クラスを継承したクラスで記述する。
    * 抽象メソッドは、子クラス側でのオーバーライドが強制される。
    * オーバーライドされないとコンパイルエラーになる。
  • Javaのabstractとは?抽象クラスの基礎とabstractの使い方

多態性(ポリモーフィズム)

  • 多態性とは次のような性質により、同一の型でも異なるふるまいをさせることができること。
  • 親クラスの型に子クラスのインスタンスが代入できる。
  • メソッド実行時は、代入された子クラスのインスタンスのメソッドが実行される。
  • 多態性とは、同一の型でも異なるふるまいをさせることができること。

[[プログラム例]] 自分と家族の紹介をコンソールに出力するプログラム

  • "Family_Super":親クラス
  • "Father_Sub", "Son_Sub", "Daughter_Sub":子クラス。親クラスの"Family_Super"を継承して作成。
  • FamilyExec_Class:子クラスを実行するクラス。
  • abstract public void eachIntroduce():個別の紹介を出力する抽象メソッド。
  • public void eachIntroduce() :子クラスで、抽象メソッドに具体的な処理を記述したメソッド。
package some.package;

//【クラス】
abstract public class Family_Super { //親クラス
	
	//フィールド
	public String familyName = "加藤";	//姓を表す
	public String givenName;	//名を表す
	public String address = "東京都中野区〇×";	//住所を表す

	// 【メソッド】
	public void commonIntroduce(String name) { //共通の紹介を出力する
		this.givenName = name; 
		System.out.println("名前は" + this.familyName + this.givenName + "です");
		System.out.println("住所は" + this.address + "です");
	}
	
	// 【抽象メソッド】
	abstract public void eachIntroduce();//個別の紹介を出力する
	
	// 【メソッド】
	public void execIntroduce() { //紹介を実行する
		this.eachIntroduce();
	}
}
package some.package;

//【クラス】
public class Father_Sub extends Family_Super{ //子クラス。親クラスのFamily_Superをextendsして作成。
	
	// 【メソッド】
	public void setGivenName() { //名を表すフィールドの値をセットする
		this.givenName = "太郎";
	}
	
	// 【メソッド】
	public void eachIntroduce() {  //抽象メソッドに具体的な処理を記述
		//System.out.println("名前は" + familyName + this.givenName + "です");
		commonIntroduce(this.givenName);
		System.out.println("私はJavaが得意です\n");
	}
}
package some.package;

//【クラス】
public class Son_Sub extends Family_Super{ //子クラス。親クラスのFamily_Superをextendsして作成。
	
	// 【メソッド】
	public void setGivenName() { //名を表すフィールドの値をセットする
		this.givenName = "一郎";		
	}
	
	// 【メソッド】
	public void eachIntroduce() {  //抽象メソッドに具体的な処理を記述
		//System.out.println("名前は" + familyName + this.givenName + "です");
		commonIntroduce(this.givenName);
		System.out.println("好きな食べ物はリンゴです\n");
	
	}
}
package some.package;

//【クラス】
public class Daughter_Sub extends Family_Super{ //子クラス。親クラスのFamily_Superをextendsして作成。
		
	// 【メソッド】
	public void setGivenName() { //名を表すフィールドの値をセットする
		this.givenName = "花子";
	}
	
	// 【メソッド】
	public void eachIntroduce() {  //抽象メソッドに具体的な処理を記述
		//System.out.println("名前は" + familyName + this.givenName + "です");
		commonIntroduce(this.givenName);
		System.out.println("趣味は読書です\n");	
	}
}
package some.package;

//【クラス】
public class FamilyExec_Class {
	
	public static void main(String[] args) {
		
		//各子クラスのインスタンスを生成する
		Father_Sub father_sub = new Father_Sub();
		Son_Sub son_sub = new Son_Sub();
		Daughter_Sub daughter_sub = new Daughter_Sub();
		
		//setGiveNameメソッドを実行する
		father_sub.setGivenName();
		son_sub.setGivenName();
		daughter_sub.setGivenName();
		
		//execIntroduceメソッドを実行する
		father_sub.execIntroduce();
		son_sub.execIntroduce();
		daughter_sub.execIntroduce();
	}

}
名前は加藤太郎です
住所は東京都中野区〇×です
Javaが得意です

名前は加藤一郎です
住所は東京都中野区〇×です
好きな食べ物はリンゴです

名前は加藤花子です
住所は東京都中野区〇×です
趣味は読書です

メモ

今からでも遅くない!クラスの継承(extends)を学ぼう!【Java】


メソッドの循環参照に注意する

Discussion