0
Help us understand the problem. What are the problem?

posted at

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

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

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()は無くてもいいみたいです。

class Dog 
    def introduce
        puts  "僕はポチだ!"    
    end
end

dog = Dog.new
dog.introduce

#僕はポチだ!

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

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

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

#モモ 

⚫︎PHP
__constructorは省略可です。

⚫︎publicprivate
publicクラスの外からアクセス可
privateクラスの内からアクセス可

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

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メソッド属性を必要とせず状態を持たないメソッドみたいです。


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

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

⚫︎PHP

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

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

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

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

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

継承

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

⚫︎Ruby

 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
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クラスを作っていきます。

#継承元 親クラス
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クラスを作っていきます。

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}です";  
    } 
   
  
}
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}だよ";  
    } 
  
}

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

#継承元 親クラス
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

#継承元 親クラス
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

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

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することができます。

参考資料

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?