### 封裝
程序只能通過被授權的成員方法才能對數據操作。如:電視機
* var $name; //var表示public
* 方法沒有寫屬性,默認public

protected,private可以通過公開的方法調用
~~~
class clerk{
public $name;
private $salary;
public function __construct($name,$salary){
$this->name=$name;
$this->salary=$salary;
}
public function getSalary($pwd){
if($pwd=='123'){
echo $this->salary;
}else{
echo '沒有訪問權限';
}
}
}
$a=new clerk('田偉',100000);
echo $a->name;
echo $a->getSalary(124);
~~~
### 訪問proteced,private的數據3種方式:
* __get(),__set()可以一次性解決所有私有屬性的操作。優點是簡單,缺點是不夠靈活,防護性比較差
~~~
<?php
class clerk{
public $name;
protected $nickname;
private $salary;
public function __construct($name,$nickname,$salary){
$this->name=$name;
$this->salary=$salary;
}
//魔術方法
public function __get($pro_name){
if(isset($this->$pro_name)){
return $this->$pro_name;
}else{
return '用戶名不存在';
}
}
public function __set($pro_name,$val){
if(isset($this->$pro_name)){
return $this->$pro_name=$val;
}else{
return '屬性不存在';
}
}
}
$a=new clerk('田偉','小偉',100000);
echo $a->name;
echo $a->nickname;
~~~

*給每個proteced ,private變量提供一個getXXX,setXXX方法。
在方法里可以進行各種效驗
~~~
<?php
class Book{
public $name;
public $author;
public $price;
private $amount=0;
function __construct($name,$author,$price){
$this->name=$name;
$this->author=$author;
}
//amout的方法
public function setAmount($num){
if(is_int($num)){
return $this->amount=$num;
}else{
echo '格式錯誤';
}
}
public function getAmount($code){
if($code=='123'){
return $this->amount;
}else{
echo '密碼錯誤';
}
}
}
$book1=new Book('紅樓夢','小曹',200);
echo $book1->setAmount('1e');
echo $book1->getAmount('123');
~~~
* 直接在類里面寫一個public方法,查詢私有屬性
### 對象運算符的連用



## 繼承
繼承父類的屬性和方法
目的是:減少代碼的冗余
**繼承是建立了子類與父類的查找關系,不是拷貝了父類。**
* 數據操作的時候,先在子類里面看查找屬性或方法,如果子類有,就不會查找父類。如果沒有,查找父類。
* 因此子類的屬性或方法會覆蓋父類的。
* 子類最多只能繼承一個父類(可以父類再繼承父類解決)
* 子類可以繼承父類的public,proteced屬性或方法
* 在創建子類對象時,如果沒有定義構造方法,默認調用父類的構造方法
* 子類中訪問父類的方法:父類::方法名,parent::方法名
* 如果子類方法和父類方法重名,稱為方法重寫。
子類調用父類的普通方法,用`$this->方法名,或parent::方法名`,或 父類名::方法名(不建議用)
子類調用父類的構造方法,用`parent::__construct();`
## 方法重載
傳統重載:同一個函數名,通過參數的不同,調用不同的方法體
PHP的重載:動態的創建屬性和方法,通過魔術方法實現的。
**非靜態方法重載:__call**
調用一個不可用或不存在的方法時,call會被觸發
**靜態方法重載:__callStatic**

## 屬性重載
通過__set,__get來實現屬性重載

## 方法重寫(覆蓋)
* 方法名和參數個數必須保持一致,類型約束也必須一致(參數的數據類型)
* 子類不能縮小父類的訪問權限,父類是proteced,子類是public,子類父類會同時調用。

如果子類沒有覆蓋父類,子類里面可以用:this->方法名,如果覆蓋了,使用父類要 parent::方法名
parent::屬性名,只能用于父類的靜態屬性。而且為public或proteced,不能用于非靜態屬性。
## 屬性重寫
public ,proteced可以被重新,private不能被重寫
## 多態
對象在不同情況下的多種狀態,通過繼承父類或接口方式實現多態
根據傳入的對象類型不同,調用對應的對象方法

## 抽象類
* 如果有一個方法不確定,可以把這個方法聲明為抽象,抽象方法不能有函數體,
* 此類必須聲明為抽象類
* 抽象類可以包含非抽象方法,可以沒有抽象方法
* 抽象類可以有成員屬性和常量
* 抽象類最主要目的在于設計,不在于實現,定義規范,讓其他類來繼承,并實現它的方法
* 抽象類不能被實例化
* 如果一個類繼承了一個抽象類,必須實現所有的抽象方法。

~~~
abstract public funciton cry();
~~~
## 接口
接口不能被實例化
接口中所有的方法都不能有主體
一個類可以實現多個接口,逗號隔開
接口中可有屬性,只能是常量 const TAX_RATE=0.08;
使用 iAbc::TAX_RATE;
接口中所有的方法都必須是public
接口不能繼承其他的類,但是可以繼承其他接口


接口是小寫的i開頭,駝峰法




## final關鍵字
final方法在父類中,不能被子類重寫覆蓋
如果類為final,此類不能被繼承
final方法是可以被實例化的
類為final,方法就沒必要再寫final