見出し画像

Java-22(型変換について〜

●勉強

▶️今回の要点

  • データには基本データ型と参照型の2種類がある。

  • 小さなデータ型から大きなデータ型に変換する場合は自動的に型変換が行われるが、逆の場合はキャストが必要になる。

  • クラス間に継承関係がある場合には、型変換が自動的に行われます。

  • サブクラスからスーパークラスへの変換では問題が発生する可能性があり、その場合にはキャストが必要になる。

▶️参照型の型変換とは

型変換する前のクラスと、変換後のクラスの間で継承関係になるときに参照型の型変換ができる。
継承関係にあるクラス同士でオブジェクトの型変換は、

スーパー = サブの時、  自動で行われる。
サブ   = スーパーの時、キャストで明示する。

▶️自動とキャストの違いとその理由

Student stu1 = new Student(...);
Person psn = stu1;

Studentクラス(入れ物の箱が大きい) > Personクラス(小さい)
ここで、stu1で扱える範囲は大きい。
逆に、psnで扱える範囲は小さい。

親クラス
Personクラス    = ▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️

子クラス
Studentクラス = ▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️ (←ここまでを継承)   + ▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️▫️ (←ここまでを追加) 

よって、箱の大きいstu1を、範囲の小さいpsnに入れることは可能。

Student stu1 = new Student(...);
Person psn = stu1;
Student stu2 = (Student)psn;
psn.display();
psn.chgStuNo(・・・);
stu2.chgStuNo(・・・);

以上の中で、

Student stu2 = (Student)psn;

ここでいう、(Student)がキャストになります。

Studentクラスの入っている要素が多い理由は、Personクラスを継承したからである。つまり、要素の少ないPersonクラスがスーパークラス(親クラス)で、要素の多いStudentクラスが参照。

スーパークラスに、サブクラスに代入する時には、自動で行われる。
なぜなら、サブクラスの中の情報には必ずスーパークラスの情報があるから、型変換するには問題はない。

しかし、スーパークラスから、サブクラスに代入する時には、要素がたくさん入った大きな箱へと広げるため、メモリ上に必ずしも存在するとは限らないので、ただ変換するとコンパイルエラーが起きるので、型変換をする時には、キャストが必要である。ということになる。

▶️サンプルプログラム

public class Person5{
  private String name;

  public Person5(String name){
    this.name = name;
  }
  public void display(){
    System.out.println("名前:" + name);
  }
}
public class Student5 extends Person5{
  private int stuNo;

  public Student5(String name, int stuNo){
    super(name);
    this.stuNo = stuNo;
  }
  public void display(){
    super.display();
    System.out.println("学籍番号:" + stuNo);
  }
  public void chgStuNo(int stuNo){
    this.stuNo = stuNo;
  }
}
public class StuSample5{
  public static void main(String[] args){
    Student5 stu1 = new Student5("菅原",1);
    Person5 psn = stu1;
    psn.display();
    // psn.chgStuNo(1001);

    /* 補足:instanceofキーワード
       オブジェクトのクラスを特定する
       対象オブジェクト instanceof クラス名 */
    if(psn instanceof Student5){
      Student5 stu2 = (Student5)psn;
      stu2.chgStuNo(1001);
      stu2.display();
    }
  }
}

●復習

▶️オーバーロードとオーバーライド

オーバーロード
・1つのクラスの中で同じ名前のメソッドを複数定義できること。
・クラスにない、同じ名前で引数の型や数が違うメソッドを定義すること。
 同じような機能を持つメソッドであっても引数のデータ型が異なれば別々
 のメソッドを用意する必要がある。

オーバーライド
・スーパークラスとサブクラスでのメソッドの上書きである。
・サブクラスで、スーパークラスのメソッドを再定義する。
 条件は、戻り値の型、メソッド名、引数の型と数が全て同じ場合。

▶️コンストラクタ

オブジェクトの初期化のための特殊なメソッド
名前がクラス名と同じであり、戻り値を持たないこと(voidを設定)
newクラス名(コンストラクタへの引数)があることが条件。
コンストラクタを定義しない→デフォルトコンストラクタが生成。

▶️static

全インスタンス変数が使える
メンバ変数やメソッドを定義する時には、staticを指定する。
クラス名.変数[メソッド]名と書きなおす必要がある。

▶️カプセル化

「アクセス修飾子」でクラス・メンバ変数・メソッドの公開範囲を指定

⦅公開範囲⦆
public
同クラス、同パッケージ、サブクラス、その他
protected
同クラス、同パッケージ、サブクラス
(なし)
同クラス、同パッケージ
private
同クラス
代入前処理ができる、修正範囲を変えやすいというメリットがある。

class Student{
  private int score;
  public void setScore(int s){
  (中略)
  score = s;
  }
}
○ stu.setScore(80);
× stu.score = 80;
//このように、直接代入をすると、コンパイルエラーが出ることになる。

▶️継承

継承関係にある親クラスをスーパークラス、子クラスをサブクラスという。extendで継承可能。

▶️this とsuper

this とsuperによるメソッド・メソッドの呼び出し
this.~ = 自オブジェクトの〜
super.~ = スーパークラスの〜
プログラムの処理を再び書く必要がない。引数名を考えなくて良い。

public class Person3{
  private String name;

  public Person3(String name){
    this.name = name;
  }
  public void display(){
    System.out.println("名前:" + name);
  }
}

this とsuperによるコンストラクタの呼び出し
this()~ = 自オブジェクトの〜
super()~ = スーパークラスの〜
これらは、コンストラクタ内の先頭に記述するようにする。
なければ、自動的にsuper();が設定されることになる。

●次回

ポリモフィズムについて

今日はここまで!


少しずつですが、投稿をしております。 noteで誰かのためになる記事を書いています。 よろしくおねがいします。