【パキスタン・シガーバレー産】天然石 アクアマリン結晶原石 75.6ct

【パキスタン・シガーバレー産】天然石 アクアマリン結晶原石 75.6ct

パトカー is-a 自動車 のように「A is-a B」のような関係にあるクラスは、継承によってクラス B のメンバをクラス A に組み込ませることができた。

// 親クラス public class A { // 親クラスのメンバ

// 子クラス
public class B extends A {
  // 子クラスのメンバ

上記のように書くと、A が持つメンバは B に組みこまれるため、B のインスタンスから A の公開メンバにアクセスすることができるようになる。

【パキスタン・シガーバレー産】天然石 アクアマリン結晶原石 75.6ct


【パキスタン・シガーバレー産】天然石 アクアマリン結晶原石 75.6ct

親クラスの引数を持つコンストラクタを呼び出すには、super という命令を使用した。

public class Person { public String name; public int age; public Person(String name, int age) { // Person インスタンスのフィールドを設定 ... ...
public class Student extends Person {
    public String studentId;
    public int grade;
    public Student(String name, int age, String id, int grade) {
        // Person(String, int) を呼ぶ
        super(name, age);
        // Student インスタンスのフィールドを設定
        this.studentId = id;
        this.grade = grade;

子クラスのインスタンスを、親クラスの型を持つ変数に代入することができた。

public class A { public void aMethod() { System.out.println("a"); }

public class B extends A {
  public void bMethod() { System.out.println("b"); }
A inst = new B();
inst.aMethod();

次の「人間」クラスについて考えてみる。

package j2.lesson05; public class Person { private final String name; public Person(String name) { this.name = name; public String getName() { return this.name; public void introduceMyself() { System.out.println(getName() + "です。");

このクラスは、public なメンバとして、getName() と introduceMyself() がある。前者はこの人の名前を取得するメソッドで、後者はこの人に自己紹介を行ってもらうメソッドである。

「人間」を継承した「学生」というクラスを作成する。

package j2.lesson05; public class Student extends Person { private final String id; public Student(String name, String id) { super(name); this.id = id; public String getId() { return this.id; public void introduceMyselfAsStudent() { System.out.println(getName() + "です。"); System.out.println("学籍番号は" + getId() + "です。");

「学生」というインスタンスは、学籍番号を取得するメソッドと学生として自己紹介をするメソッドを持つ。通常の自己紹介との違いは、名前だけでなく学籍番号も一緒に表示している点である。

Java では、親クラスで宣言したメソッドを子クラスで上書きすることができる。上書きのしかたは簡単で、子クラスで親クラスと同じ名前、同じ引数を持ったメソッドを宣言するだけである。

package j2.lesson05; public class Student extends Person { private final String id; public Student(String name, String id) { super(name); this.id = id; public String getId() { return this.id; public void introduceMyself() { System.out.println(getName() + "です。"); System.out.println("学籍番号は" + getId() + "です。");

上記の例では、Person で宣言した introduceMyself() を Student で上書きしている。getName() は Student クラスには存在していないが、Person クラスを継承しているため使用することができる。

子クラスでメソッドを上書きすると、呼び出し時には子クラスのメソッドが呼び出される。

Student student = new Student("ほげほげ", "00k0000"); student.introduceMyself();

ほげほげです。
学籍番号は00k0000です。



また、他の子クラスを作成する際にも同じことができる。

package j2.lesson05; public class Professor extends Person { private final String office; public Professor(String name, String office) { super(name); this.office = office; public String getOffice() { return this.office; public void introduceMyself() { System.out.println(getName() + "です。"); System.out.println("オフィスは" + getOffice() + "です。");

こちらも Person クラスで宣言した introduceMyself() を上書きしている。Student 同様、以下のようなプログラムが書ける。

Professor prof = new Professor("ふーばー", "W4999"); prof.introduceMyself();

ふーばーです。
オフィスはW4999です。

上記のように、親クラスのメソッドを上書きすることをメソッドのオーバーライド

先ほどの例で挙げた3つのクラスの introduceMyself() メソッドについて見直してみる。

public class Person { ... public void introduceMyself() { System.out.println(getName() + "です。");

public class Student extends Person {
    ...
    public void introduceMyself() {
        System.out.println(getName() + "です。");
        System.out.println("学籍番号は" + getId() + "です。");
public class Professor extends Person {
    ...
    public void introduceMyself() {
        System.out.println(getName() + "です。");
        System.out.println("オフィスは" + getOffice() + "です。");







実際にプログラムを書いてみると、次のようになる。

これを、Javaのプログラムで記述すると次のようになる。

例えば、タクシーは次のようにかけるかもしれない。

ポリモーフィズムを実感できる例として、toString() メソッドがある。

しかし、toString() というメソッドは子クラスでオーバーライドして、そのクラスごとの動作を規定しないと意味の分からない文字列を返す。

Object person = new Person("ほげほげ"); System.out.println(person.toString());

[email protected]

上記はプログラムを実行した結果で、j2.lesson05.Personクラスの toString() メソッドを呼び出したことは推測できるが、その中身がなにであるかは想像できない。

ここで意味のある文字列を表現させたい場合、toString() メソッドを Person クラスでオーバーライドする必要がある。

package j2.lesson05; public class Person { ... public String toString() { return "人間:" + getName();

これだけで、先ほどのプログラムの実行結果は変化する。

人間:ほげほげ

また、toString() というメソッドはさまざまなところで使用される。例えば、先ほどの例ではわざわざ toString() メソッドを呼び出して文字列に変換した後、その文字列を表示していた。

System.out.println(person.toString());
Object person = new Person("ほげほげ"); System.out.println(person);
コンソールに文字列を表示する際には、当然のように文字列を表示する

アクセス制御子をこれまでにいくつか紹介したが、メソッドのオーバーライドや継承などを含めて、いくつか追加する。

キーワード クラス内 パッケージ内 子クラス内 その他
public
protected ×
なし × ×
private × × ×

フィールドにメソッドをつけると、そのフィールドに特定の場面以外で代入ができなくなった。クラスやフィールドに final をつけると、継承を行う際にいくつか制限がかかる。

クラスに対して final を指定すると、そのクラスを継承することが禁止される (子クラスを作れなくなる)。Java に標準で組み込まれているクラスを調べてみると、System クラスや String クラスが public final class として宣言されている。

public final class String { ...

メソッドに対して final を指定した場合、そのメソッドをオーバーライドすることが禁止される