RubyとPHPの比較(クラス、インスタンス、継承、オーバーライド)

# この記事の概要
Rubyで学習を始めてPHPに言語チェンジをする人が一定数いるみたいなので
そういった人達が参考にするための記事です。

これらの記事の続きです。

https://qiita.com/Hashimoto-Noriaki/items/82beae9d3d6dac11e11c
https://qiita.com/Hashimoto-Noriaki/items/449c00327e99574e430a
https://qiita.com/Hashimoto-Noriaki/items/96eadd7076675fe19dc9


# クラス

⚫︎```Ruby```

```rb
class  Dog
    def initialize(name,kind,weight)
        @name = name
        @kind = kind
        @weight = weight
    end
    
    def feed(eat)
        @weight += 1
        puts  "重さ:#{@weight}kg"
    end
    
    def introduce
        puts "僕は#{@kind}の#{@name}だよ！"
    end
 end   

# インスタンス作成
  #newはinitializeメソッドを呼び出す
dog1 = Dog.new("ポチ","柴犬",5)
dog2 = Dog.new("モモ","チワワ",3)

dog1.feed("ドックフード")
dog2.feed("肉")

#重さ:6kg
#重さ:4kg
```

⚫︎```PHP```

```php
class Dog {   #クラス名  クラスの中に変数やメソッドをまとめておくことができる
     private $name;  //属性(メンバー変数)
     private $kind; 　//変数(メンバー変数)
     private $weight;　//変数(メンバー変数)
    
     public function __construct($name,$kind,$weight)　{

   $this ->name = $name;   //引数をメンバー変数に代入
   $this ->kind = $kind;  
   $this ->weight = $weight;
}
 
 public function feed($eat){
     $this->weight += 1;
     echo "重さ:{$this->weight}kg";
 }

public function introduce() 
 {
     echo "僕は{$this->kind}の#{$this->name}だよ！";
 }

}

//インスタンスの作成
$dog1 = new Dog("ポチ","柴犬",5);
$dog2 = new Dog("モモ","チワワ",3);

$dog1->feed("肉");
$dog2->feed("肉");
$dog1->feed("肉");

//重さ:6kg重さ:4kg重さ:7kg
```
コードの補足をしていきます。

1. ***クラスの中で変数名を定義***する時は```private```を使います。

2. ***クラスの中でメソッド名を定義***する時は```public```を使います。

3. ***メンバ変数にアクセス***する時は```$this->```を使います。
```$this```は***自分のクラス(今回はDogクラス)を表す***ものです。

4. ```->```のことを```アロー```と言います。
これは***クラスの中の変数やメソッドを呼び出す***ためのものです。

5. ```__constractメソッド```は引数で受け取った***name,kind,weightを
メンバ変数に対して代入する***コードです。

6.```new```は***__constructメソッドを呼び出し***ます。


### 初期化メソッドのコンストラクタ
***クラスを初期化***するメソッドを```コンストラクタ```と言います。

⚫︎```Ruby```
***Ruby***では```initialize()```を使います。

⚫︎```PHP```
***PHP***では```__constructor()```を使います。


### それぞれの使い方

⚫︎```Ruby```
***initialize()は無くてもいい***みたいです。

```rb
class Dog 
    def introduce
        puts  "僕はポチだ！"    
    end
end

dog = Dog.new
dog.introduce

#僕はポチだ！
```

⚫︎```attr_accessor```
Rubyでクラスの内と外から属性の読み書きができます。

```rb
class Dog 
    attr_accessor :name, :kind, :weight
    def introduce
        puts  "僕はポチだ！"    
    end
end

dog = Dog.new
dog.name = "モモ"　#name属性の上書き
puts dog.name

#モモ 
```



⚫︎```PHP```
***__constructorは省略可***です。

⚫︎```public```と```private```
・```public```は***クラスの外からアクセス可***
・```private```は***クラスの内からアクセス可***

```php
class Constructor {
  public  $public_training;  //クラスの外から読み書き
  private $private_training;//クラスの内から読み書き
  
  //クラスの外から呼び出し
  public function  practice_Public() {
          
  }
  
  //クラスの外から呼び出せない
  private function  practice_Private() {
         
  }
    
}

//インスタンス作成
$constructor = new Constructor();

//メンバ変数
$constructor->public_training = 1; //ok
$constructor->$private_training = 1; //エラー

//メソッド
$constructor->practice_Public();
$constructor-> practice_Private(); //エラー
```

⚫︎注意
基本的にはpublicではなくprivateがいいみたいです。

### 定数
***変わらない値***のことです。

⚫︎```Ruby```
```rb
class Monkey
    KIND = "猿"
    MY_ARMS = 2
    MY_LEGS = 2

  def arm_count 
      "#{KIND}の腕は#{MY_ARMS}本です。"  #　定数参照
  end
  
  def leg_count
      "#{KIND}の足は#{MY_LEGS}本です"
  end
  
end

monkey = Monkey.new
puts monkey.arm_count  #猿の腕は2本です。
puts Monkey::MY_ARMS   #2      # クラスの外から定数を参照


puts monkey.leg_count  #猿の足は2本です
puts Monkey::MY_LEGS   #2
```
***定数は大文字とアンダーバー***で書きます。

```staticメソッド```は***属性を必要とせず状態を持たないメソッド***みたいです。

```rb

class Monkey 
    def initialize(name)
       @kind = kind
    end
     
     
    def kind
         "私は#{@kind}です"
    end
    
    #staticメソッド
    def self.eat(fee)
         "僕は#{fee}が食べたい"  
    end
end

puts Monkey.eat("バナナ")　#僕はバナナが食べたい

```




⚫︎```PHP```
```php
class Monkey {
      const KIND = "手長サル";  #constで定数を宣言
     
      public function ArmCount() {
         return self::KIND;　　//クラスの中から定数を参照　　self::KINDを書く
     }
}

echo Monkey::KIND  //手長サル    //定数をクラスの外から参照　クラス名::定数;
```

```staticメソッド```は***属性を必要とせず状態を持たないメソッド***みたいです。

```php
class Monkey {
     public static function eat($fee) {
         return "僕は{$fee}が食べたい";
     }
}

echo Monkey::eat("バナナ"); //僕はバナナが食べたい
````



# 継承
継承について最後見ていきます。
```継承```とは***別のクラスを引き継ぐこと***です。
2つのクラスがあります。猿と犬を呼ぶクラスです。

⚫︎```Ruby```
```rb
 def initialize(name,kind,)
       @name = name
       @kind = kind
       @weight = weight
    end
     
    def eat(fee)
        @weight += 1
        puts "体重:#{@weight}kg"
    end
     
    def introduce
         "私は#{@kind}の#{@name}です"
    end
end
```


```rb
class Dog
     def initialize(name,kind,)
       @name = name
       @kind = kind
       @weight = weight
    end
     
    def eat(fee)
        @weight += 1
        puts "体重:#{@weight}kg"
    end
     
    def introduce
         "私は#{@kind}の#{@name}だよ"
    end
end
```

これらの共通しているコードをまとめてzooクラスを作っていきます。

```rb
#継承元　親クラス
class Zoo
    def initialize(name,kind,weight)
        @name = name
        @kind = kind
        @weight = weight
    end
    
    def eat(fee)
         @weight += 1
         puts "体重:#{@weight}kg"
    end
end


#継承先(機能を引き継いだ方を子クラス)
class Monkey < Zoo  #<クラス名　zooクラスの機能を引き継いで、別のクラスを定義
    def introduce
        puts  "私は#{@kind}の#{@name}です"
    end
end

#継承先(機能を引き継いだ方を子クラス)
class Dog < Zoo　#<クラス名　zooクラスの機能を引き継いで、別のクラスを定義
    def introduce
    puts "私は#{@kind}の#{@name}です"
    end

end
```
⚫︎補足
***継承は何段階も作れます***。
***子クラスを継承***した```孫クラス```も作れます。




⚫︎```PHP```
こちらでもMonkey,Dogクラスを作っていきます。

```php
class Monkey {
   public $name;
   public $kind;
   private $weight;
   
    
   public function __constructor($name,$kind,$weight)
   {
    $this->name = $name;
    $this->kind = $kind;
    $this->weight = $weight;
    
   }
   
   
   public function eat($fee) {
    $this->weight += 1;
    echo "体重:{$this->weight}kg";
   }
      
    public function introduce()
    {
      echo "私は{$this->kind}の{$this->name}です";  
    } 
   
  
}
```

```php
class Dog {
   public $name;
   public $kind;
   private $weight;
   
    
   public function __constructor($name,$kind,$weight)
   {
    $this->name = $name;
    $this->kind = $kind;
    $this->weight = $weight;
    
   }
   
   
   public function eat($fee) {
    $this->weight += 1;
    echo "体重:{$this->weight}kg";
   }
      
    public function introduce()
    {
      echo "私は{$this->kind}の{$this->name}だよ";  
    } 
  
}
 ```

これを元に継承をしていきます。

```php
#継承元　親クラス
class Zoo {
    public  $name; 
    public $kind ;
    private $weight; 
    
 public function __constructor($name,$kind,$weight){
    $this ->name = $name;
    $this ->kind = $kind;
    $this ->weight = $weight;
 }   
 
 public function eat($fee) {
    $this ->weight += 1;
    echo  "体重:{$this->weight}kg";
 }
}



class Monkey extends Zoo {　　//extends クラス名　　zooクラスを引き継いで定義する
     public function introduce()
     {
         echo "私は{$this->kind}の{$this->name}です"; 
     }
}


class Dog extends Zoo {
     public function introduce()
     {
         echo "私は{$this->kind}の{$this->name}だよ"; 
     }
}
```
***Monkey,DogクラスはZooクラスに機能は全部使えます***。
こちらも```継承```です。継承の要領はRubyと同じです。







## オーバーライド
プログラミングでの***上書き***は```オーバーライド```と言います。
***親クラスで引き継いだ機能を子クラスで上書き***されるということです。


⚫︎```Ruby```

```rb
#継承元　親クラス
class Zoo
    attr_accessor :weight
    
    def eat(fee)
         @weight += 1
         puts "体重:#{@weight}kg"
    end
end

#こちらで上書きされる
class Monkey < Zoo  
    #3kgずつ増える   
    def eat(fee)
         @weight += 3
         puts "体重:#{@weight}kg"
    end
end

#ここは上書きされない
class Monkey < Zoo
    #1kgずつ増える
    
end
```

⚫︎```PHP```

```php
class Zoo {
    public  $name; 
    public $kind ;
    private $weight; 
    
 public function __constructor($name,$kind,$weight){
    $this ->name = $name;
    $this ->kind = $kind;
    $this ->weight = $weight;
 }   
 
 public function eat($fee) {
    $this ->weight += 1;
    echo  "体重:{$this->weight}kg";
 }
}

#こちらで上書きされる
class Monkey extends Zoo {
     public function eat($fee)
     {
         $this ->weight += 2;
         echo "私は{$this->kind}の{$this->name}です"; 
     }
}

#ここは上書きされない
class Dog extends Zoo {
     //1kgずつ増える
}
```


### module
人間クラスと動物クラスを作ります。
どちらも食べる機能はあるのでeatメソッドを作りたいところですが
人間と動物だと親子関係にならず上書きができないです。
Animalクラスを継承して人間クラスを作ることができないです。
ここで```module```を使います。これは***部品***という意味で***クラスの一部分を切り取ったものです。***


⚫︎```Ruby```

```rb
module Eat
    attr_accessor :weight
    def eat(fee)
         @weight += 3
         puts "体重:#{@weight}kg"
    end
end


class Animal
    include Eat
end


class Human
    include Eat
end

  human = Human.new
  human.weight  = 40
  human.eat #体重:43kg
```
AnimalとHumanクラスでは```moduleをinclude文```で囲みます。
これでmoduleの機能のeatメソッドを使えるようになりました。
そして複数のモジュールをincludeすることができます。


# 参考資料
https://www.youtube.com/watch?v=8NI57SrDiVw&list=PL-1KBX2gDRuiDf7R-YR4NjFf_nYu3RG3y&index=16

https://www.youtube.com/watch?v=J_pASVQXElA