ProgateでJavaを学ぶ【コース5はクラスの継承など】

ProgateでJavaコース5

progate javaコース5

この記事ではProgateというプログラミングの学習サービスで学んだことをまとめています。

Progateはコース2,3あたりの途中から有料になります。

有料はちょっとっていう方は筆者がまとめた記事を読んでいただけるとよいかもしれません↓

Progate Javaコース5はJavaの最終コースになります。コース4がかなり量が多くて難しい印象がありましたが、オブジェクト指向を理解したい人はこの本を買ってもよいかもしれません↓

Progateはあまり細かいことまで突っ込まず重要なところだけをきっちりとやっていく感じなので、細かく知りたい人は本買ってもよいかもしれないですね。

ProgateのJavaのコース5はオブジェクト指向をより深くまなんでいくコースになります。

それではコース5で学んだことをかきたいと思います

クラスの継承

クラスの継承は新たにクラスを作るときに機能を追加したいときに位置から作るのが面倒なので親クラスの部品を引き継がせて子クラスで使えるようにするものです。

継承元のクラス: 親クラス
継承して新たに生み出したクラス: 子クラス

といいます。

javaの継承は extends キーワードを使います。余談にはなりますがRubyだと <記号 Pythonは クラス名(クラス名): のように書きます。 クラス継承の簡単な例を書きたいと思います


class Person{
private String name;
Person(String name){
  this.name = name;
}
public void getName(){ 
  return this.name;
}
public String setName(String name){
  this.name = name;
}

putlic void printData(){
  System.out.println("名前:" + this.name);
}
}

class BusinnesPerson extends Person{
//親のフィールドとかメソッドが使える
}

//main.java
class Main {
  public static void main(String[] args) {
    BusinnesPerson person1 = new BusinnesPreson("tanaka");
    System.out.println(person1.getName() + "さんこんにちは");//tanakaさんこんにちは
  }
}

BusinnesPersonのインスタンスに対してgetName()メソッドが呼び出せるのは親クラスを継承しているからです。

メソッドオーバーライド

メソッドオーバーライドは子クラスで親クラスのメソッドを上書きできるようにしたものです。重複部分があるときにメソッドオーバーライドを使うと簡略化できるなどの利点があるようです。

class Person{
private String name;
Person(String name){
  this.name = name;
}
public void getName(){ 
  return this.name;
}
public String setName(String name){
  this.name = name;
}

putlic void printData(){
  System.out.println("名前:" + this.name);
}
}

class BusinnesPerson extends Person{
//親のフィールドとかメソッドが使える
private int age = 20;
//メソッドオーバーライド
putlic void printData(){
  System.out.println("名前:" + this.getName());
  System.out.println("年齢:" + this.age + "歳");
}
}

//main.java
class Main {
  public static void main(String[] args) {
    BusinnesPerson person1 = new BusinnesPreson("tanaka");
    person1.printData();
  }
}

superキーワード

superキーワードを使うと親クラスのメソッドを使うことができます。下記はあまり意味のないコードですが、コードが多くなってくるとsuperを使ってコードを少なくできるようです。

class Person{
private String name;
Person(String name){
  this.name = name;
}
public void getName(){ 
  return this.name;
}
public String setName(String name){
  this.name = name;
}

putlic void printData(){
  System.out.println("名前:" + this.name);
}
}

class BusinnesPerson extends Person{
//親のフィールドとかメソッドが使える
private int age = 20;
//メソッドオーバーライド
putlic void printData(){
 super.printData();//親クラスのメソッドを呼ぶ
  System.out.println("年齢:" + this.age + "歳");
}
}

コンストラクターのオーバーライド

オーバーライドはメソッドを上書きするものですがコンストラクターも同様に使うことができます。よくやるのはsuper()をつかって親クラスのコンストラクターをよぶやつです。

class Person{
private String name;
Person(String name){
  this.name = name;
}
public void getName(){ 
  return this.name;
}
public String setName(String name){
  this.name = name;
}

putlic void printData(){
  System.out.println("名前:" + this.name);
}
}

class BusinnesPerson extends Person{
private int age = 20;
//メソッドオーバーライド
putlic void printData(){
 super.printData();//親クラスのメソッドを呼ぶ
  System.out.println("年齢:" + this.age + "歳");
}
//コンストラクターのオーバーライド
BusinessPerson(String name, int age){
  super(name);//親のコンストラクターを呼び出している。
  this.age = age;
}
}

protected修飾子

private修飾子だと親クラスも外部クラスとみなされてしまいます(子クラスからみて)ゲッターとセッターが定義されている場合はこれをつかってアクセスできるのですが、ゲッターとセッターなしで直接親クラスのフィールドにアクセスしたいときがあります。

そういうときは protectedなフィールドを定義すればよいようです。

class Person{
private String name;
protected String clothes = "ジーパン"//protectedな変数clothes 
Person(String name){
  this.name = name;
}
public void getName(){ 
  return this.name;
}
public String setName(String name){
  this.name = name;
}

putlic void printData(){
  System.out.println("名前:" + this.name);
  System.out.println("洋服:" + this.clothes);//ゲッターなしで直接アクセス可能
}
}

class BusinnesPerson extends Person{
private int age = 20;
//メソッドオーバーライド
putlic void printData(){
 super.printData();//親クラスのメソッドを呼ぶ
  System.out.println("年齢:" + this.age + "歳");
}
//コンストラクターのオーバーライド
BusinessPerson(String name, int age){
  super(name);//親のコンストラクターを呼び出している。
  this.age = age;
}
}

抽象メソッド抽象クラス

抽象クラスは実装忘れを防ぐための仕組みみたいですが筆者もちょっと利点がよくわかっていません。ただポイントは以下のようなものです。

  • 抽象メソッドの書き方 「abstract アクセス修飾子 void メソッド名();」→処理をかくことができない
  • 抽象メソッドを1つでももったクラスは抽象クラスとなり「abstract class クラス名{}」とかく。このクラスはインスタンス化することができない。
  • 抽象メソッドは子クラスで必ず定義しなければならない

コードは省略します。

クラス型のフィールド

クラス型のフィールドの話は書いてもたぶんよくわからないので、あまり書きませんが、クラスを継承せずに別のクラスの部品(メソッド)をつかいたいときに使うときがあるみたいです。

クラス型のフィールドとは今までみてきたように「Person person1 = new Person();」の Person person1がPersonクラスのフィールドperson1ということです。これを継承せずに別のクラスに定義しようというわけです。

class Car {
  private Person owner;//Personクラス型の変数
  public Person getOwner(){
    return this.owner;
  }
  public void setOwner(Person person){
    this.owner = person;
  }
  public void hello(){
  System.out.println("hello hello");
}
}

class Person{
  public void hello(){
  System.out.print("hello world");
}
}


class Main{
public static void main(String[] args) {
Person person1 = new Person();
Car car = new Car();
car.setOwner(person1);setOwnerメソッドをつかってCarクラスに定義してあるowner変数にインスタンスをセット
car.getOwner.hello();//hello world。Personクラスのhello()メソッドがよばれている
}
}

申し訳ありませんがこのコードはデバッグして確認してるわけではありませんので間違っている可能性はあります。ただ考え方としてはこんなかんじです。クラスAにクラスB型の変数が定義できるということですね。といっても筆者もなにがわかってないかよくわかってないのでここはとばしていただいたほうがよいかもしれません。

多態性

クラス型変数の重要な点は多態性のようですがこれの使いどころもよくわかりません。Progateも結構難しいです。

多態性とは 親クラス型の変数に 子クラスのインスタンスを代入できるというものです

親クラス 変数 = new 子クラス(); みたいに書くのですが使いどころがよくわからしコードも長くなるので省略します。

Proagte コース5まとめ

ProgateのJavaコースもこれで終わりです。最後の方はただ打っているだけでなにが凄いのかよくわからずじまいでした。とりあえず今回の内容をまとめます。

  • クラスの継承: 新しくクラスをつくるときに機能をひきつぐ | class 子クラス名 extends 親クラス{}
  • メソッドオーバーライド: 子クラスで親クラスのメソッドを書き換える
  • super(): 親のメソッドやコンストラクターを呼ぶ | super()はコンストラクターを呼ぶ super.メソッド名()でメソッドを呼ぶ
  • protected: 親子でアクセスできるようにする | ゲッターとセッターがないときとかにつかう
  • 抽象メソッド: 親でメソッド宣言だけして子で必ず実装する | abstract アクセス修飾子 void メソッド名();
  • 多態性: 親クラスの変数に子クラスのインスタンスを入れれる

最後のクラス変数のとこがいまいちまだわかってないですが、とりあえずクリア。

以上。