継承したクラスを動かす
クラスの継承関係を作成して、それを実行してクラス継承の意味と使い方を理解していきます。
その第一回目となります。
前回の記事ではアクセス修飾子の継承関係を作ったときにどのような違いがあるのか記載しています。
親クラスと子クラスを実行イメージ
JFrameクラスを継承して画面作成
Java Swingで、幅300, 高さ300の画面に座標(100,100)から幅100、高さ100の円を0度から300度までの線を引きました。JFrameを継承、paint()をオーバーライドします
前提
以下のクラスを作成します。親、子(兄)、子(弟)、メインクラス
- Parent(親)
- ChildAni(兄)
- ChildOtoto(弟)
- MainFamilly(メインクラス)
それぞれ以下のようなコードです。
そして、MainFamilyクラスはメインメソッドを持っているクラスです。このクラスを用意することでほかのクラスを修正してもメインメソッドを修正せずに起動できるというわけです。
具体的には以下のような手順で起動確認しながら実装ができるというわけです。
- MainFamilly以外のクラスを修正する
- MainFamillyクラスのメインメソッドを起動する
Parent
下に定義している子クラスが継承するクラスです。このクラスは、フィールド変数に「public static」のものと「protected」のものがあります。このフィールド変数は、子クラスから参照することができます。が「private」になっている変数は参照できません。
public class Parent {
/** 家計 */
public static int kakei = 1000;
/** 苗字 */
protected String lastName;
/** 名前 */
private String name;
/** 年齢 */
private int age;
/** 趣味・特技 */
public String favorit;
/** コンストラクタ */
public Parent() {
lastName = "tanaka";
name = "takao";
age = 50;
favorit = "ケツで箸を割る";
}
/** 自己紹介 */
public void say() {
System.out.println(lastName + "と申します。");
System.out.println("親です。名前は" + name + "です。年齢は" + age + "です。");
System.out.println("特技は、「" + favorit + "」です。");
}
/** おかしな部分 */
protected void funny() {
System.out.println("喜びを真逆の言葉で表現する。");
}
/** 買い物 */
public void buy(int money) {
kakei -= money;
System.out.println("残金:" + kakei);
}
}
ChildAni
子クラス1です。Parentクラスを継承しています。Parentクラスの「Say()」メソッドをオーバーライドしています。
public class ChildAni extends Parent {
/** 年齢 */
private int age;
/** 名前 */
private String name;
public ChildAni() {
name = "taro";
age = 12;
}
@Override
public void say() {
System.out.println(lastName + "です。");
System.out.println("兄です。名前は" + name + "です。年齢は" + age + "です。");
System.out.println("特技は、「" + favorit + "」です。");
}
}
ChildOtoto
子クラス2です。Parentクラスを継承しています。Parentクラスの「Say()」メソッドをオーバーライドしています。
public class ChildOtoto extends Parent {
/** 年齢 */
private int age;
/** 名前 */
private String name;
public ChildOtoto() {
name = "jiro";
age = 10;
favorit = "鼻を膨らます";
}
@Override
public void say() {
System.out.println(lastName + "といいます。");
System.out.println("弟です。名前は" + name + "です。年齢は" + age + "です。");
System.out.println("特技は、「" + favorit + "」です。");
}
@Override
public void funny() {
super.funny();
}
}
MainFamilly
public class MainFamilly {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("**** Game Start ****");
Parent parent = new Parent();
ChildAni ani = new ChildAni();
ChildOtoto ototo = new ChildOtoto();
while (true) {
String input = scan.nextLine();
if ("parent".equals(input)) {
parent.say();
} else if ("ani".equals(input)) {
ani.say();
} else if ("ototo".equals(input)) {
ototo.say();
} else {
System.out.println("処理を終了します。");
break;
}
}
}
}
実践してみましょう
まずは、MainFamillyクラスを起動してみましょう。
実行結果はどのようなものでしょうか?
ParentクラスChildAniクラスの違いは以下の部分です。
Parentのコンストラクタ
/** コンストラクタ */
public Parent() {
lastName = "tanaka";
name = "takao";
age = 50;
favorit = "ケツで箸を割る";
}
Parent#say()
/** 自己紹介 */
public void say() {
System.out.println(lastName + "と申します。");
System.out.println("親です。名前は" + name + "です。年齢は" + age + "です。");
System.out.println("特技は、「" + favorit + "」です。");
}
ChildAniのコンストラクタ
public ChildOtoto() {
name = "jiro";
age = 10;
favorit = "鼻を膨らます";
}
ChildAni#say()
@Override
public void say() {
System.out.println(lastName + "です。");
System.out.println("兄です。名前は" + name + "です。年齢は" + age + "です。");
System.out.println("特技は、「" + favorit + "」です。");
}
ポイント
使用しているフィールド変数は全く同じものでしょうか?確認してみてください。アクセス修飾子をみて判断しましょう。
アクセス修飾子は下のような意味があります。
アクセス修飾子
public: どこからでも参照できる
protected: パッケージ内、クラスの継承関係がある場合に参照できる
private: クラスの中でのみ参照できる
まとめ1
アクセス修飾子によって、継承関係を作成したクラスの間で、参照する変数が変わります。
この特性を使用して、変数名が同じでも参照する変数が変えることができます。
「だからなに?」と聞かれそうですが、ここでの言いたいことはクラス固有の変数を持つことができるというところです。
ご先祖を作る
上記の記述では、Parent, ChildAni, ChildOtotoの3クラスを作成しました。ここまでで、クラスの継承に関しては理解できたと思います。注意点としてはアクセス修飾子です。この違いが理解できればオッケーです。
そして次の話に行きます。「ご先祖を作成する」というふうにきさいしましたが、抽象クラスを作成する方向で話を進めます。
抽象クラスとは
こちらの記事に記載されていたのは下のような文言です。
抽象クラスの代表的なクラスがあります。それは「Calendarクラス」です。このクラスは、抽象クラスなので「new」できません。
なので、「Calendar.getInstance();」のようにインスタンス取得メソッドを使用します。
このメソッドを使用してインスタンスを取得する方法は、「new」するときに固定の方法をプログラマーに強制させることができます。
つまり、ほかの方法で「new」できないということです。
抽象クラスとは、抽象メソッドを 1 つ以上持つクラスです。そのクラスだけでは意味を持たず、サブクラスに継承されることで初めて機能します。
抽象メソッドとは、以下のように記述されるメソッドです。abstract の後に、戻り値の型、メソッド名、引数の型、引数の数のみを定義し、処理内容は実装されません。具体的な処理内容は、抽象クラスを継承するサブクラスで実装されます。
早い話が、下のように通常のクラスに「抽象メソッドを持っている」というところです。
アクセス修飾子 abtract 戻り値の型 メソッド名(引数);
サンプルコード(ご先祖)
public abstract class Gosenzo {
/** 秘伝 */
public String hiden;
public Gosenzo() {
hiden = "秘伝のタレ";
}
/** 血継限界 */
protected abstract String kekkeiGenkai();
}
このご先祖クラスを親クラスに継承します。
そうすると、ビルドエラーが出ます。
このビルドエラーは、「抽象メソッドのオーバーライド」を行ていないために出たエラーです。
つまり、抽象メソッドを実装することを強制できるというわけです。逆に言うとGosenzoクラスを継承したクラスは、必ずkekkeiGenkai()メソッドがあるということです。
当然、抽象クラスにはメソッドの中身(処理)を書いていないので、Gosenzoクラスを継承したクラスは、必ずkekkeiGenkai()を持っていることになります。
具体的に、ご先祖を継承したParentクラスの血継限界が「"Hello Japan!"」を標準出力へ出力するものでParent2クラスの血継限界が「"Good Night"」を標準出力へ出力するものだったとします。
そうしたときに、下のようなコードを使用するとGosenzoクラスの中小メソッドを使用することで、kekkeiGenkai()の処理内容を別のものにすることができます。
public static void main(String[] args) {
Gosenzo g1 = new Parent();
Gosenzo g2 = new Parent2();
g1.kekkeiGenkai();
g2.kekkeiGenkai();
}
これが、抽象クラスの扱い方の一つです。
しかし、、実際にはこのようなクラス関係を作成することはありません。わかりやすいように作っているだけです。具体的には「デザインパターン」を使用したり、自分で考えたクラス関係を特定の目的のために作ります。
次回予告
次回は、作成した上記のクラスを修正していろいろと動かしてみます。
でわでわ。。。
関連ページ一覧
- Java Install Eclipse〜開発ツールのインストール〜
- TensorFlow C++環境〜EclipseにCDTをインストール〜
- Setup OpenGL with Java〜JOGLを使う準備 for Eclipse〜
- Eclipse Meven 開発手順〜プロジェクトの作成〜
- Java OpenCV 環境セットアップ(on Mac)
- Eclipse SceneBuilderを追加する
- JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
Java Basic一覧
- Java Basic Level 1 〜Hello Java〜
- Java Basic Level2 〜Arithmetic Calculate〜
- Java Basic Level3 〜About String class〜
- Java Basic Level 4〜Boolean〜
- Java Basic Level 5〜If Statement〜
- Java Basic Summary from Level1 to 5
- Java Basic Level 6 〜Traning of If statement〜
- Java Basic Level8 〜How to use for statement〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 9〜Training of for statement〜
- Java Basic Level 10 〜While statement 〜
- Java Basic Swing〜オブジェクト指向〜
- Java Basic Swing Level 2〜オブジェクト指向2〜
- サンプル実装〜コンソールゲーム〜
- Java Basic インターフェース・抽象クラスの作り方
- Java Basic クラスとは〜Step2_1〜
- Java Basic JUnit 〜テストスイートの作り方〜
Git関連
- Java Git clone in Eclipse 〜サンプルの取得〜
- Eclipse Gitリポジトリの取得 〜GitからソースをPullしよう〜
- IntelliJ IDEA Git〜Gitリポジトリからクローン〜
JavaFX関連ページ
- Eclipse SceneBuilderを追加する
- JavaFX SceneBuilder 〜EclipseとSceneBuilder連携~
- JavaFX SceneBuilder〜ボタンにメソッドを割り当てるワンポイント〜
- Java プロコンゲーム 〜見た目の作成(SceneBuilderの使用)〜
ステップアップ関連ページ一覧
- Java 初めてでも大丈夫〜ステップアッププログラミングのススメ〜
- ステップアッププログラミング〜Java FxでHelloWorld解説〜
- Java StepUpPrograming〜JavaFX で四則計算〜
- Java StepUpPrograming〜JavaFXで画面切り替えを作る1〜
- Java StepUpPrograming〜JavaFXで画面切り替え2ボタン作成〜
- Java StepUpPrograming〜JavaFXで画面切り替え3アクション〜
- Java StepUpPrograming〜JavaFXで画面切り替え4Pane切り替え〜
- Java StepUpPrograming〜JavaFXで画面切り替え5WebEngine
JavaFX + ND4Jで機械学習準備
- JavaFX + ND4J〜数学への挑戦1:ND4Jのインストール〜
- JavaFX + ND4J〜数学への挑戦2: 行列の計算〜
- Java + ND4J 〜数学への挑戦3: ベクトル(配列)の作成方法〜
オブジェクト指向関連ページ
- [オブジェクト指向の概念1〜OracleDocのチュートリアル1〜](https://zenryokuservice.com/wp/2019/10/301. /%e3%82%aa%e3%83%96%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e6%8c%87%e5%90%91%e3%81%ae%e6%a6%82%e5%bf%b5-%e3%80%9coracledoc%e3%81%ae%e3%83%81%e3%83%a5%e3%83%bc%e3%83%88%e3%83%aa%e3%82%a2%e3%83%ab%ef%bc%91/)
- オブジェクト指向の概念2〜クラスとは〜