クラス間の継承を作る〜準備編:アクセス修飾子を理解する〜

イントロダクション

「基本文法がわかったから、簡単なプログラムなら組めるようになった。」は、「戦いの舞台に立った」状態です。
ここからが、戦いの始まりです。上の「基本文法がわかった」は処理を行う「メソッドが作れるようになった」ということです。これができないと始まらな。。。

今度は、この「メソッド」を自在に呼び出してメンテナンスのしやすいシステムを組みましょうというのが目標になります。

まとめると次のような形です。

  • 基本文法の理解:メソッドを作れるようになった。
  • クラスの扱い方の理解:メンテナンスのしやすいシステムを組める

ある意味「永遠のテーマ」ですが「メンテナンスのしやすいシステム」を組めるように良い設計=良いプログラムを組めるようになる。
これが、目標になります。

クラスの継承

クラス継承の方法は、簡単です。下のようにコードを書けば良いです。

public class Child1 extends Parent { ... } 

継承関係を作ると、子クラスが親クラスの実装を受け継ぎ拡張することができます。

クラスの継承関係を作るときはクラス毎に役割を分担し、実装の依存関係を分断できるように作ります。詳細は下のリンクを参照下さい

Java クラスの扱い〜役割分担をする〜

クラスの書き方などは下のリンクを参照下さい。
Java Basic Class 〜クラスを作ってクラスを理解する〜
Java Basic Class 〜クラスを使うサンプル〜

プログラムコードにすると下のような形です。

/** 親クラス */
public class Parent {
    private int age;
    private String name;

    /** コンストラクタ */
    public Parent(String name) {
        this.age = 24;
        this.name = name;
    }
    public void greet() {
        System.out.println("Hello World");
    }
    public void call() {
        System.out.println("Help!");
    }
}

/** 子クラス */
public class Child extends Parent {
    /** コンストラクタ */
    public Child() {
        super("Takunoji");
    }
    @Override
    public void greet() {
        System.out.println("Hello Brother");
    }
}

親クラス(Parent)を継承して子クラス(Child)を作成しています。
【ポイント1】
「new」したときに起動するコンストラクタは子クラスで「suepr()」を使用して親クラスのコンストラクタを呼び出しています。

【ポイント2】
子クラスのメソッド「greet()」は親クラスのメソッドをオーバーライドしています。

<オーバーライドのサンプル>
この動画では、JFrameクラスを継承してクラスを作成しています。親クラスのメソッド「paint()」メソッドをオーバーライドしています。

つまり、オーバーライドすると子クラスのメソッドが呼び出されるということです。
※親クラスのオブジェクト(インスタンス)で呼び出した場合は親クラスのメソッドが呼ばれます。

public static void main(String[] args) {
    Parent parent = new Parent("Taro");
    parent.greet();// Parentクラスのメソッド
    parent.call();// Parentクラスのメソッド

    Child child = new Child();
    child.parent(); // Childクラスのメソッド(オーバーライドしている)
    parent.call();// Parentクラスのメソッド
}

継承したときのテクニック

継承関係を作ることのメリットとしては、同じコードを書かなくてよいところです。
上の例では、変数のアクセス修飾子を「private」にしているので子クラスから参照することができませんが
これを「protected」に変更してやれば、子クラスでもフィールド変数「age, name」を参照することができます。

また、メソッドでオーバーライドしているもの(greet())とそうでないものがあります(call())がそれぞれ子クラスのインスタンスから呼び出すことができますが、オーバーライドしているメソッドは親クラスのメソッドを呼び出すことができません。それは、オーバーライドしているからです。
もし、呼び出したいのであれば、子クラスの中で「super.call()」と書く必要があります。

ここからが本題です。

アクセス修飾子

継承関係を作成したあとには、フィールド変数や、メソッドを定義します。

これらは「メンバ」と呼ばれインスタンスを生成して使用する事が多いです。インスタンスを生成しない場合はstatic修飾子をつけて使用します。

前置きはさておきにして具体的な使い方などに触れていきます。

変数のスコープprivate

まずは、下の様にクラスの継承関係を作ります。

親クラス

public class Parent {
    protected static int kakei = 1000;
    protected Stirng lastName;
    private String name;
    private int age;
       /** コンストラクタ */
       public Parent() {
          lastName = "test";
          name = "taro";
          age = 50;
       }
    public void say() {
       System.out.println("My name is " + name + " " + lastName + " and " + age + "years old.");
    }
}

子クラス

public class Child1 {
    private String name;
    private String age;
    public Child1 {
       name = "polo";
       age = 15;
    }
    @Overeide
    public void say() {
      System.out.println("My name is " + name + " " + lastName + " and " + age + "years old.");
    }
}

メインメソッド

public static void main(String[] args) {
    Parent p = new Parent();
    p.say();
    Child1 c1 = new Child1();
    c1.say));
}

そして、上の様な処理を実装したら
どんな出力が得られるでしょうか?
注意点としては、アクセス修飾子により、アクセスするフィールド変数が異なるところです。実行して確かめてみてください。

変数のスコープprotected

次は、protectedについて見てみます。
ParentクラスのlastNameに着目してください。2つのクラスの出力は、「test」になったと思います。これは継承関係があるクラス間で共有出来る、スコープが継承関係のあるクラス間で使用出来る様になっているからです。※パッケージ内でも使える様です。
これらのクラスのコードをいじっていろんな出力を確認してみてください。
きっと、クラスの継承とはどんなものか?の答えが見えて来ると思います。
実際に作る時は、UML など使うとわかりやすいと思います。
例えば、RPGゲームを作ろうとした場合には、以下のような登場人物がいます。

  • ゲームプレイする「プレーヤー・キャラクター」
  • モンスターなどのコンピュータが操作する「ノンプレイヤー・キャラクター」

それぞれの登場人物を「クラス」で表現してみると継承関係を作るメリットがより明確に分かると思います。
Java テキストRPG(戦闘シーンのみ)を再作成する~LWJGLを参考に作り直す~
Java テキストRPG(戦闘シーンのみ)を再作成する2~設計からやり直す~


でわでわ。。。

次回 >>>

関連ページ一覧

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す