2018年11月29日 星期四

OOP of PHP & Python(物件導向)

封裝Encapsulation 
物件導向的類別是一種資料結構data structure ,可以在{}中包含變數和函數。這些變數與函數統稱為“成員” ,變數被稱為其類別的“屬性”,函數被稱為其類別的“方法”。

能否從類別外部呼叫類別成員由類別宣告的方法控制。
Public
Private
Protected
Public可以從外部呼叫
private將拒絕呼外部叫類別變數,但允許內部呼叫
這種可以存儲和檢索這些變數成員的數據的方法。可以讓數據隱藏確保儲存的數據安全地封裝在類別變數成員中,是物件導向(OOP)的原理之一。

類別宣告以class關鍵字開始,後跟一個空格,然後是程序員指定的類別名稱 ,必須遵循的PHP命名約定,但以大寫開頭。接下來是類別屬性宣告,後面跟著類別方法聲明宣告。這些類似於常規變量和函數宣告,但每個都應以類別宣告開頭。類別宣告語法如下所示:

#PHP封裝
<?php
class vw {
    public $color; //宣告你要的屬性($color 不是變數)
    public function setColor($c) {
          $this->color = $c; //這裡跟函數寫法不同.如此才能被物件使用.
              return $this->color;
     }
} //類別vw

$vw = new vw;
echo $vw->setColor('none');
echo "<br>";
?>

#python封裝
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
         self.setColor = c
vwColor = vw('none') # 宣告一個類別為vw的物件
print(vwColor.setColor) # 使用物件的公開變數


繼承 Inheritance
我們可以將PHP類別創建為全新的類別,如前面示例中的類別,或者可以從現有類別“繼承”。重要的是,除了自己的成員之外,繼承類別還繼承它的父(基礎)類別的成員。從基礎類別繼承成員的能力允許創建繼承類別,這些繼承類別共享某些已在基類別中定義的公有屬性。 繼承的優點非常強大,是物件導向編程(OOP)的第二個原則。繼承類別宣告在其類名後面添加extends關鍵字,後跟它繼承的類別的名稱:

#PHP繼承
<?php
class vw {
    public $color; //宣告你要的屬性($color 不是變數)
    public function setColor($c) {
        $this->color = $c; //這裡跟函數寫法不同.如此才能被物件使用.
          return $this->color;
     }
} //類別vw

class golf extends vw { 
} //類別繼承


$vw = new vw;
$golf = new golf;
echo $vw->setColor('none');
echo "<br>";
echo $golf->setColor('red');
echo "<br>";
?>

#複寫繼承
<?php
class vw {
    public $color;
    public function setColor($c) {
       $this->color = $c;
         return $this->color;
    }
} //類別vw

class golf extends vw {
    public $year;
    public function setYear($y) {
       $this->year = $y;
         return $this->year;
     }
} //複寫繼承

$vw = new vw;
$golf = new golf;
echo $vw->setColor('none');
echo "<br>";
echo $golf->setColor('red');
echo "<br>";
echo $golf->setYear('2018');
echo "<br>";
?>


#python繼承
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
      self.setColor = c

class golf(vw): #繼承
    def __init__(self,c):
       super().__init__('golf color:'+c)

vwColor = vw('none')
golfColor = golf('red')
print(vwColor.setColor)
print(golfColor.setColor)

#python繼承複寫
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
      self.setColor = c

class golf(vw):
    def __init__(self,c):
      super().__init__('golf color:'+c) #繼承

def setYear(self):
      return '2018'

vw = vw('none')
golf = golf('red')

print(vw.setColor)
print(golf.setColor)
print(golf.setYear()

#python複寫函式,新增參數
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
      self.setColor = c
    def setYear(self):
          pass

class golf(vw): #繼承
    def __init__(self,c,door):
          super().__init__('golf color:'+c)
          self.door = door

    def setYear(self):
           return '2018'

vw = vw('none')
golf = golf('red',4)

print(vw.setColor)
print(golf.setColor,',doors:',golf.door)
print('year:',golf.setYear())


多型Polymorphism
物件導向編程(OOP)的三個基石是封裝,繼承和多型。在前面我們已經了解瞭如何將數據封裝在PHP類別中,以及如何繼承其類別的屬性,因此我們現在可以探索多型的原理。“多型”(來自希臘語,意思是“許多形式”)描述了根據其上下文為實體分配不同含義或目的的能力。例如,在現實世界中,每個人都知道如何使用按鈕(實體) - 您只需對其施加壓力即可。但是,該按鈕的作用取決於連接到它的內容(上下文),但結果不會影響該按鈕的使用方式。在物件導向編程的世界中,多型允許類別在共享公有接口時具有不同的功能。取用物件時不需要知道它正在使用哪個類別,因為它們像真實世界按鈕一樣,都以相同的方式使用,但可以產生不同的上下文結果。以這種方式擁抱多型態使程序員能夠創建可根據需求選擇的可互換對象,而不是通過條件測試。 PHP接口類似於類,但是使用interface關鍵字聲明,並且只能包含方法定義,而不包含要執行的任何方法語句,如下所示:

實現接口的每個類別必須通過指定要執行的語句來實現它定義的所有方法。通過在其聲明中包含implements關鍵字和接口名稱,將類附加到接口,如下所示:

#PHP多型
<?php
interface vw {
     public function setColor($c);
     public function setYear($y);
}

class golf implements vw {
     public $color;
     public function setColor($c) {
          $this->color = $c;
            return $this->color;
     }

      public $year;
      public function setYear($y) {
          $this->year = $y;
            return $this->year;
      }
}

#繼承
class passat extends golf{
}

$golf = new golf;
echo "golg color:".$golf->setColor('red');
echo "<br>";
echo "golf years:".$golf->setYear('2018');
echo "<br>";

$passat = new passat;
echo "passat color:".$passat->setColor('black');
echo "<br>";
echo "passat years:".$passat->setYear('2017');
echo "<br>";
?>

#python多型
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
      self.setColor = c
    def color(self):
          return self.setColor
    def setYear(self):
          pass

class golf(vw): #繼承
    def __init__(self,c):
          super().__init__('golf color:'+c)

    def setYear(self):
          return ',years:2018'

class passat(): #多型
    def __init__(self,c):
          self.setColor = 'passet color:'+c
    def color(self):
          return self.setColor
    def setYear(self):
         return ',years:2017'

    def vwShow(obj):
         print(obj.color(), obj.setYear())

vw = vw('none')
vwShow(vw)
golf = golf('red')
vwShow(golf)
passat = passat('black')
vwShow(passat)

#python多型(簡化)
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
        self.setColor = c
    def color(self):
        return self.setColor

class golf(vw): #繼承
    def __init__(self,c):
         super().__init__('golf color:'+c)


class passat(): #多型
    def __init__(self,c):
        self.setColor = 'passet color:'+c
    def color(self):
       return self.setColor

    def vwShow(obj):
        print(obj.color())

vw = vw('none')
vwShow(vw)
golf = golf('red')
vwShow(golf)
passat = passat('black')
vwShow(passat)


#多型(與繼承無關)
class vw:
    def __init__(self,c): # 在類別內的函是參數self與c
         self.setColor = c
    def color(self):
        return self.setColor

class passat(): #多型(與上面相同的函示)
    def __init__(self,c):
         self.setColor = 'passet color:'+c
    def color(self):
        return self.setColor

    def vwShow(obj):
         print(obj.color())

vw = vw('none')
vwShow(vw)
passat = passat('black')
vwShow(passat)