見出し画像

iT-20-[JAVA]

復習

設計図クラス
属性→何のデータを持っているのか。
操作→何の処理ができるか。

クラスから作られる実体(モノ)を、object(オブジェクト)と呼ぶ。
オブジェクトを中心にプログラムを作っていくことを、
オブジェクト指向という。

メリット

→開発効率、保守性、メモリ効率、システム化など!!

変数、メソッドの定義

戻り値の型 メソッド名(引数リスト){
(処理)
}

引数・・呼び出し元から受け取る値のこと。
戻り値・・メソッドの処理の後に、呼び出しもとに返す値。
 returnで指定することができる。何も返さない場合は、voidを記述する。

オブジェクトの使い方

①オブジェクト生成
クラス名 オブジェクト名 = new クラス名();
Student stul = new Student( );
→プログラムにおいて、オブジェクトを作ることをインスタンス化という。

②変数・メソッドを利用すること
オブジェクト名.変数名
オブジェクト名.メソッド名(引数)
stul.name = "菅原";
stul.setScore(80,90);

オーバーロードとは

クラスにない、同じ名前で引数の型や数が違うメソッドを定義すること。

呼び出すメソッドは、名前と因数の組み合わせで決めている。

同じような機能を持つメソッドであっても引数のデータ型が異なれば別々のメソッドを用意する必要がある。

class Student {
  void setData(String n){
            (中略)
    }
  void setData(String n, int e, int m){
            (中略)
    }            
main(~){
  Student syu = new Student();
  stu.setData("菅原");
  stu.setData("菅原", 80, 90);
}

メリット

・プログラム自体がわかりやすくなる。
→同じデータを設定するためのメソッドなので、setDataという同じ名前にした方が、同じような処理をしているのが見た目でわかる。
・名前をつけるのがラクになる
→同じ名前をつけても使えるから。
・メソッド名が変わらないので、とても使いやすい。例えば、printlnメソッドもクラスで使われているので、オーバーロードを使うとすごく便利になる。

class Student2{
  String name;
  int engScore;
  int mathScore;

  void setData(String n){
    name = n;
  }
  void setData(String n, int e, int m){
    name = n;
    engScore = e;
    mathScore = m;
  }
  void setScore(int e, int m){
    engScore = e;
    mathScore = m;
  }
  void display(){
    System.out.println(name + "さん");
    System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
  }
}
class StuSample2{
  public static void main(String[] args){
    Student2 stu1 = new Student2();
    Student2 stu2 = new Student2();

    stu1.setData("菅原");
    stu1.setScore(90, 80);
    stu1.display();

    stu2.setData("村山", 75, 100);
    stu2.display();
  }
}

コンストラクタ

construction(組み立てる)
オブジェクトの初期化のために使われる特殊なメソッド

① 名前がクラス名と同じ
②  戻り値を持たない
③ newクラス名(コンストラクタへの引数

コンストラクタを定義しない場合は、自動でデフォルトコンストラクタ(引数&処理なし)が生成される。
例 Student(){}

class Student{
  Student(String n){
}

コンストラクタもメソッドの一つなので、オーバーロードできる。

class Student {
  void setData(String n){
            (中略)
    }
  void setData(String n, int e, int m){
            (中略)
    }            
main(~){
  Student syu = new Student("管原");
  Student syu = new Student("村山", 75, 100);
}

最初、コンストラクタを定義していなかったので、コンパイル時に自動でデフォルトコンストラクタを生成されていた。なので、自分で設定いしてもいいということだ。

生成と同時に値を入れられるので、安全という訳だ。

staticとは

作ったインスタンスの個数を知る方法は?

class Student{
  int counter = 0;
  Student(){
    counter ++;
  }
}

インスタンス内の変数では、むり。
前インスタンスが共通して使える変数が必要!

class Student{
  static int counter = 0;

  Student(){
    counter ++;
  }
  
  static void display(){
    System.out.println(counter + "人です");

}

全インスタンス変数が使えるメンバ変数やメソッドを定義する時には、staticを指定する。
オブジェクトを生成していなくても利用できる。
利用方法
クラス名.変数[メソッド]名と書く!重要

・全部のインスタンスから共通して使う変数やメソッドを作る時に使う。

サンプルコード

class Student4{
  String name;
  static int counter = 0;

  Student4(String n){
    name = n;
    counter++;
    System.out.println(name + "さんをインスタンス化しました");
  }
  static void display(){
    System.out.println(counter + "人です");
  }
}
class StuSample4{
  public static void main(String[] args){
    Student4.display();

    Student4 stu1 = new Student4("菅原");
    Student4.display();

    Student4 stu2 = new Student4("村山");
    Student4.display();
  }
}


カプセル化とは

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

修飾子・・public, protected, (なし), private
同クラス・  ○    ○     ○    ○
同パッケージ ○    ○     ○
サブクラス   ○    ○
他       ○

メンバ変数は、隠蔽(private)して、クラスとメソッドは公開(publiv)する設計方針をカプセル化と呼ぶ。
代入前処理、修正範囲

class Student{
  private int score;
  public void setScore(int s){
  (中略)
  score = s;
  }
}
○ stu.setScore(80);
× stu.score = 80;

サンプルコード

public class Student5{
  private String name;
  private int score;

  public Student5(String n){
    name = n;
  }
  public void setScore(int s){
    if(0 <= s && s <= 100){
      score = s;
    } else {
      System.out.println(name + "さんの点数が範囲外です");
      score = 0;
    }
  }
  void display(){
    System.out.println(name + "さん:" + score + "点");
  }
}
class StuSample5{
  public static void main(String[] args){
    Student5 stu1 = new Student5("菅原");
    stu1.setScore(80);
    stu1.display();
    
    Student5 stu2 = new Student5("村山");
    stu2.setScore(-50);
    // stu2.score = -50;
    stu2.display();
  }
}

前回の練習問題


breakメソッドが、オーバーロード
同じメソッド名で、引数が違うものがあるので、それを確認する課題だ。

class Car1{
  int no;
  int speed;

  void setNo(int n){
    no = n;
  }
  void run(int s){
    speed = s;
  }
  // brakeメソッドを定義する

  void display(){
    System.out.println("ナンバー" + no + "の速度は" + speed + "です");
  }
}
class DriveCar1{
  public static void main(String[] args){
    Car1 c1 = new Car1();
    c1.setNo(2525);
    c1.run(30);
    c1.display();
    
    c1.brake(10);
    c1.display();
  }
}

戻り値の型→void
引数は、speed = speed -sで使用。

class Car1{
  int no;
  int speed;

  void setNo(int n){
    no = n;
  }
  void run(int s){
    speed = s;
  }
  

   // brakeメソッドを定義する
  void brake(){
    speed = 0;
  }

    void break(int s){
    speed = speed - s
  }
  //brakeメソッドを定義できた! 
   
  void display(){
    System.out.println("ナンバー" + no + "の速度は" + speed + "です");
  }
}
class DriveCar1{
  public static void main(String[] args){
    Car1 c1 = new Car1();
    c1.setNo(2525);
    c1.run(30);
    c1.display();
    
    c1.brake(10);
    c1.display();
  }
}

コンストラクタが、引数ありなしで宣言。

①コンストラクタを設定
→名前は、クラス名に合わせる。
→戻り値を持たない。


②setNoは削除する

class Car2{
  int no;
  int speed;

  //コンストラクタをここに書けばいい↓
    Car2(){
    no = 0;
  }
  Car2(int n){
    no = n
  }
    //ここまでがコンストラクタである。
     
  void run(int s){
    speed = s;
  }

  void brake(){
    speed = 0;
  }

  void brake(int s){
    speed = -s;
  }

  void display(){
    System.out.println("ナンバー" + no + "の速度は" + speed + "です");
  }
}
class DriveCar2{
  public static void main(String[] args){
    Car2 c1 = new Car2();
    c1.run(30);
    c1.display();
    
    Car2 c2 = new Car2(2525);
    c2.run(50);
    c2.display();
  }
}

コンストラクトをどこに設定すればいいかがわからない。


アクセス修飾子
→メンバ変数には、private
→コンストラクタとメソッドには、publicを設定すること。

class Car3{
    //メンバ変数にはprivate
  private int no;
  private int speed;

  //コンストラクタにはpublic
  public Car3(){
    no = 0;
  }
  public Car3(int n){
    no = n;
  }
  
  //メソッドには、public
  public void run(int s){
    speed = s;
  }
  public void brake(){
    speed = 0;
  }
  public void brake(int s){
    speed = speed - s;
  }
  public void display(){
    System.out.println("ナンバー" + no + "の速度は" + speed + "です");
  }
}


ただし、↓の8行目のままやってしまうと、コンパイルエラーが出ることになる。

カプセル化のメリットである。

class DriveCar3{
  public static void main(String[] args){
    Car3 c1 = new Car3();
    c1.run(30);
    c1.display();
    
    Car3 c2 = new Car3(2525);
    c2.speed = 50;
    // c2.run(50);
    c2.display();
  }
}

これを、8行目をコメントアウト、9行目を表示させてみる。

class DriveCar3{
  public static void main(String[] args){
    Car3 c1 = new Car3();
    c1.run(30);
    c1.display();
    
    Car3 c2 = new Car3(2525);
    //c2.speed = 50;
    c2.run(50);
    c2.display();
  }
}

カプセル化をすることで、

変数への直接代入を禁止させることができる。

これを、代入前処理という。設計図クラスの中で、たとえばif文などを設定しておくことで、間違った値などを入れた時にエラーが出てくれるようにしてくれる。

例えば、100点満点のテストがあった時に、80点を入れれば何も問題はないが、180点を入れてしまった時にカプセル化をしていないとそのまま実行されてしまう。テストは100点なので、その範囲で入れてね〜というエラーを出すことができるようになるということだ。
メソッドのみで値を出すようにすることで、不正な値を減らせるし、ログをとっておける。

先ほどのDriveCar3クラスにて、8行目がc2.speedに直接代入している。
(下の状態ではマズいということです)
もし、メンバ変数にprivateのアクセス修飾子を入れていなかった場合、別のクラスからもこうやって直接アクセスして代入してしまうことができてしまう。なので、メソッドを呼び出すように設計図で決めていても、呼び出す側が.speedで代入できてしまうという状態になってしまっていることがよくないということになる。

これを防げるのが、privateである。

class DriveCar3{
  public static void main(String[] args){
    Car3 c1 = new Car3();
    c1.run(30);
    c1.display();
    
    Car3 c2 = new Car3(2525);
    c2.speed = 50;
    // c2.run(50);
    c2.display();
  }
}

コンパイルした時点でエラーが出るので、他の開発者にメソッドを経由してねと言葉だけでなく強制させることができる。

もう一つは、修正範囲が狭くてメンテナンスがしやすいという利点がある。

カプセル化をしておくと、Scoreを、mathScoreにしたいとおもったら、
設計図の中だけを修正すればよい。
しかし、.speedみたいに、直接代入を実行用クラスに入れておくと、
実行用クラスも.mathScoreみたいに編集する必要が出てくる。

つまり、一つのクラスを編集すれば変更が可能。

しかし、直接代入を複数のクラスで行ってしまった場合、その全てを変えなくてはいけなくなる。そうすると、メンテナンスが最強に無駄になる。


class Car4{
  private int no;
  private int count = 0;

  public Car4(){
    no = 0;
    count++;
    System.out.println("ナンバーなしを作りました");
  }
  public Car4(int n){
    no = n;
    count++;
    System.out.println("ナンバー" + no + "を作りました");
  }
  public void display(){
    System.out.println(count + "台作成済です");
  }
}
class DriveCar4{
  public static void main(String[] args){
    Car4 c1 = new Car4();
    c1.display();
    Car4 c2 = new Car4(2525);
    c2.display();
    Car4 c3 = new Car4(8888);
    c3.display();
  }
}

各インスタンスが、共通して使うために、static変数を使う。

データ型の前にstaticを入れる。
displayメソッドの前にもstaticを入れる。

また、

呼び出す側も変わる。
変数名.メソッド

→クラス名.変数名、メソッド名.変数名に変える必要がある。

///////////////////////////////////変更前

class Car4{
  private int no;
  private int count = 0;

  public Car4(){
    no = 0;
    count++;
    System.out.println("ナンバーなしを作りました");
  }
  public Car4(int n){
    no = n;
    count++;
    System.out.println("ナンバー" + no + "を作りました");
  }
  public void display(){
    System.out.println(count + "台作成済です");
  }
}
///////////////////////////////////変更後

class Car4{
  private int no;
  private static int count = 0;

  public Car4(){
    no = 0;
    count++;
    System.out.println("ナンバーなしを作りました");
  }
  public Car4(int n){
    no = n;
    count++;
    System.out.println("ナンバー" + no + "を作りました");
  }
  public static void display(){
    System.out.println(count + "台作成済です");
  }
}

実行用クラスは、

///////////////////////////////////変更前

class DriveCar4{
  public static void main(String[] args){
    Car4 c1 = new Car4();
    c1.display();
    Car4 c2 = new Car4(2525);
    c2.display();
    Car4 c3 = new Car4(8888);
    c3.display();
  }
}
///////////////////////////////////変更後

class DriveCar4{
  public static void main(String[] args){
    Car4 c1 = new Car4();
    Car4.display();
    Car4 c2 = new Car4(2525);
    Car4.display();
    Car4 c3 = new Car4(8888);
    Car4.display();
  }
}

これによって、

これによって、自動車を何台作ったのか(インスタンスどうし)を合計してカウントすることができるようになった!!
すげ〜〜!!

勉強


継承

継承とは、既存のクラスをもとに変数やメソッドを追加したクラスを作ること。継承関係にある親のクラスをスーパークラス、子のクラスをサブクラスという。

メンバ変数と、メソッドをそのままかけるので、
①コーディングがらくになる!!
②メンテナンスがらくになる!!
→名前のクラスが、スーパークラスにしかない!

継承できるクラスは1つだけ。
また、コンストラクタは継承しない。

extendを入れることによって、継承できる。

public class Person{
  private String name;

  public void setName(String n){
    name = n;
  }
  public void display(){
    System.out.println("名前:" + name);
  }
}
public class Student extends Person{
  private int stuNo;

  public void setStuNo(int s){
    stuNo = s;
  }
  public void displayStuNo(){
    System.out.println("学籍番号:" + stuNo);
  }
}
public class StuSample{
  public static void main(String[] args){
    Student stu = new Student();

    // スーパークラスのメソッド
    stu.setName("菅原");    
    stu.display();

    // サブクラスのメソッド
    stu.setStuNo(1);
    stu.displayStuNo();
  }
}

extend スーパークラス名で継承できる!!

オーバーライド

・サブクラスで、スーパークラスのメソッドを再定義することをオーバーライドという。

条件は、戻り値の型、メソッド名、引数の型と数が全て同じ場合。

オーバーロードとは、1つのクラスの中で同じ名前のメソッドを複数定義できること。
オーバーライドとは、スーパークラスとサブクラスでのメソッドの上書きである。

//スーパークラスPerson2

public class Person2{
  private String name;

  public void setName(String n){
    name = n;
  }
  public String getName(){
    return name;
  }
  public void display(){
    System.out.println("名前:" + name);
  }
}
//スーパークラスを継承した、サブクラスStudent2(設計図クラス)

public class Student2 extends Person2{
  private int stuNo;

  public void setStuNo(int s){
    stuNo = s;
  }
  public void display(){
    System.out.println("名前:" + getName());
    System.out.println("学籍番号:" + stuNo);
 / }
}
//StuSample2(実行用クラス)

public class StuSample2{
  public static void main(String[] args){
    Student2 stu = new Student2();
    stu.setName("菅原");    
    stu.setStuNo(1);
    stu.display();
  }
}

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()~ = スーパークラスの〜

同じクラスの中でのコンストラクタ、スーパークラスの中でのコンストラクタを利用できる。

また、注意として、
this()~ = 自オブジェクトの〜
super()~ = スーパークラスの〜

は、コンストラクタ内の先頭に記述するようにする。
なければ、自動的にsuper();が設定されることになる。

サンプルコード

public class Person3{
  private String name;


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

  //コンストラクタ2つ
  public Student3(String name){
    this(name, 999);
  }
  public Student3(String name, int stuNo){
    super(name);
    this.stuNo = stuNo;
  }
    
  public void display(){
    super.display();
    System.out.println("学籍番号:" + stuNo);
  }
}
public class StuSample3{
  public static void main(String[] args){
    Student3 stu = new Student3("菅原");
    stu.display();
  }
}

まとめ

継承とは、既存のクラスをもとに変数やメソッドを追加したクラスを作ること。継承関係にある親のクラスをスーパークラス、子のクラスをサブクラスという。extend を入れることによって、継承できる。

オーバーロードとは、
1つのクラスの中で同じ名前のメソッドを複数定義できること。
オーバーライドとは、
スーパークラスとサブクラスでのメソッドの上書きである。

メンバ変数や、メソッドの呼び出す時に使う。
this.~ = 自オブジェクトの〜
super.~ = スーパークラスの〜

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

ここまで!だんだんわかってきたぞ〜〜。

モチベーション名言

今日から始めました。所ジョージさんの名言が結構好きなんですけど、最近知ったのが、

自分に価値を持ってない人は
お金がかかる。
 
自分の方が価値があると思う人は
お金関係ない
 

という名言でした。
ああ、金ピカの指輪とか、色々なネックレスをつけて楽しんでいる人がいる。それはそれでいいんだけど、人からよく見られようとか、ステータスとカナンとかという理由で自分の身体に価値をくっつける。
でも、それは価値がくっついているだけ。その人自身のかちではない。

手に職をつけたわけでもないし、実力があるかどうかなんてわからない。

美輪明宏さんのトークショーかなんかで聞いたことで、
派手な服装をしたり、見栄えがいいものをつけているけど、その服を脱いだ身体はブヨブヨでみすぼらしかった。
逆に、一見ボロボロの服を着ていても、その方の身体は筋肉質で、鍛えられていた。
どっちがかっこいいかは明らかだって。
あんなおしゃれな美輪明宏さんがいうんだから、そういうことだ。

その人自身の価値は、自由な発想や知的好奇心、向上心や行動力から生まれる。そこにお金は関係はないんだ。
お金で解決できるものも多いし、豊かに生きることができるが、
豊かさを作ることや、新たな価値を生む人にはなれない。
お金は大切。でも、それ以上に大切なものを考えるきっかけになった。

今日はここまで!!

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