PHP類的封裝性、繼承性和多型性
一、類的封裝性
1、什麼是類的封裝性
1)類的三大特性:封裝性、繼承性、多型性;
2)封裝性:將敏感的資料保護起來,不被外界訪問;還可以理解為,將一個功能的方方面面,封裝成一個整體,即類;
3)類的封裝性,是通過訪問許可權修飾符來實現的;
4)在專案中,屬性基本都是私有的。通過公有的方法,對私有的屬性進行賦值和取值。
2、訪問許可權修飾符介紹
1)public(公共的許可權):在任何地方都可以被訪問,主要是類內、類外、子類中都可以被訪問。
2)private(私有的許可權):只能在本類中被訪問,類外和子類中無權訪問。
3)protected(受保護的許可權):只能在本類中和子類中被訪問,在類外不能訪問。
3、例項:封裝一個簡單的資料庫工具類
//定義一個數據庫工具類 class Db { //私有的資料庫配置屬性 private $db_host;//主機名 private $db_user;//使用者名稱 private $db_pass;//密碼 private $db_name;//資料庫名 private $charset;//字符集 private $link = null;//連線資源 //公共的構造方法:資料庫物件初始化 public function __construct($config = array()) { $this->db_host = $config['db_host']; $this->db_user = $config['db_user']; $this->db_pass = $config['db_pass']; $this->db_name = $config['db_name']; $this->charset = $config['charset']; //一個小功能定義一個方法,兩個方法的功能不能相同 //一個方法只做一件事 $this->connectDb();//連線資料庫 $this->selectDb();//選擇資料庫 $this->setCharset();//設定字符集 } //私有的連線mysql伺服器的方法 private function connectDb() { if(!$this->link = @mysqli_connect($this->db_host,$this->db_user,$this->db_pass)) { echo "連線伺服器失敗!"; die(); } } //私有的選擇當前資料庫 private function selectDb() { if(!mysqli_select_db($this->link,$this->db_name)) { echo "連線資料庫失敗!"; die(); } } //私有的設定字符集 private function setCharset() { mysqli_set_charset($this->link,$this->charset); } } //建立資料庫物件 $arr=[ 'db_host' => 'localhost', 'db_user' => 'root', 'db_pass' => '666666', 'db_name' => 'hsz', 'charset' => 'utf8' ]; $db = new Db($arr); var_dump($db);
二、類的繼承性
1、什麼是類的繼承性?
1)如果一個B類擁有了A類的所有特徵資訊,我們就說B類繼承了A類。
2)A類可以稱為:基礎類(最頂層的類)、父類、上層類。
3)B類可以稱為:最終類(最終的類)、子類、下層類。
4)提示:如果多個子類擁有相同的屬性和方法,可以將相同的屬性和方法提取出來,放到“父類”中,然後,再建立子類並繼承父類;這樣一樣,重複的程式碼只寫一遍,減少程式碼量,提高工作效率。
5)為什麼要使用類的繼承?是為了實現功能的升級和擴充套件。
6)功能的升級:原來有的功能,在子類進行完善。
7)功能的擴充套件:原來沒有的功能,在子類增加新功能。
2、繼承的語法格式
3、單繼承和多繼承
1)單繼承:只能從一個父類來繼承功能。如:Java、PHP、C#等。
2)多繼承:同時從多個父類來繼承功能。如:C++
圖片.png
4、例項:單繼承的簡單演示
//定義一個學生類
class Student
{
const TITLE = "<h2>學生資訊</h2>";
public static $count = 100;
public $name = "和尚周";
public function showInfo()
{
return __METHOD__;
}
public static function readMe()
{
return __METHOD__;
}
}
//定義清華學生類,並繼承學生類
class QinghuaStudent extends Student
{
public function printInfo()
{
$str = self::TITLE;
$str .= "學生人數:".self::$count;
$str .= "<br>姓名:".$this->name;
$str .= "<br>呼叫成員方法:".$this->showInfo();
$str .= "<br>呼叫靜態方法:".self::readMe();
echo $str;
}
}
//建立清華學生類物件
$stu = new QinghuaStudent();
$stu->printInfo();
結果如下:
圖片.png
5、parent關鍵字
1)self代表當前類,parent代表父類。
2)self和parent可以存在於所有方法(成員方法和靜態方法)中。
3)self用來呼叫本類的內容,包括:類常量、靜態屬性、靜態方法、成員方法;
4)parent用來呼叫父類的內容,包括:類常量、靜態屬性、靜態方法、成員方法;
5)self和parent都使用範圍解析符"::"來呼叫其它內容。也可以叫靜態化呼叫方式。
6)語法:parent::類常量 | 靜態屬性 | 靜態方法 | 成員方法
圖片.png
三、類的多型
1、什麼是類的多型?
1)類的多型,就是類的多種形態。
2)類的多型主要指方法過載或方法重寫。
3)方法過載:在同一個類中定義兩個同名方法,PHP不支援。
4)方法重寫:在子類中定義一個與父類同名的方法,就是“方法重寫”。
5)為什麼要重寫方法?主要是實現功能的升級。父類中有的方法,子類中再用同樣的名字再定義一次,一般來說,子類中方法的功能比父類更完善、更詳盡。
2、方法重寫的要求
1)子類中重寫的方法,要與父類中的方法同名;
2)子類中重寫的方法形參個數,要與父類中的同名方法形參個數一致;
3)子類中重寫的方法型別,要與父類中同名方法型別一致,要是靜態方法都是靜態方法,要是成員方法都是成員方法。
4)子類中重寫的方法的訪問許可權,不能低於父類中同名方法的訪問許可權;
a、父類方法許可權為public,子類同名方法許可權只能是public;
b、父類方法許可權為protected,子類同名方法許可權可以是protected和public;
c、父類方法許可權為private,子類無法繼承,也無法重寫。
5)注意:對於重寫構造方法,就比較特殊,就沒有形參個數的要求。
示例:
//定義一個學生類
class Student
{
//靜態方法
public static function readMe($name,$age)
{
echo "{$name}的年齡是{$age}歲";
}
}
//定義清華學生類,並繼承學生類
class QinghuaStudent extends Student
{
public static function readMe($v1,$v2)
{
echo "{$v1}=>{$v2}";
}
}
//呼叫QinghuaStudent的靜態方法
QinghuaStudent::readMe('heshangzhou',100);
結果:heshangzhou=>100
3、例項:商品子類重寫商品基礎類中的方法
//定義基礎商品類
class Shop
{
//私有的商品屬性
private $name;
private $price;
//受保護的構造方法
protected function __construct($name,$price)
{
$this->name = $name;
$this->price = $price;
}
//受保護的顯示商品資訊
protected function showInfo()
{
$str = "商品名稱:{$this->name}";
$str .= "<br>商品價格:{$this->price}";
return $str;
}
}
//定義手機商品類
class Mobile extends Shop
{
//私有的手機屬性
private $pinpai;
private $city;
//重寫構造方法
public function __construct($name,$price,$pinpai,$city)
{
parent::__construct($name,$price);
$this->pinpai = $pinpai;
$this->city = $city;
}
//重寫父類的showInfo方法
public function showInfo()
{
$str = parent::showInfo();
$str .= '<br>手機品牌:'.$this->pinpai;
$str .= '<br>手機產地:'.$this->city;
echo $str;
}
}
//定義圖書類
class Book extends Shop
{
//私有的圖書屬性
private $author;
private $publish;
//重寫構造方法
public function __construct($name,$price,$author,$publish)
{
parent::__construct($name,$price);
$this->author = '<br>圖書作者:'.$author;
$this->publish = '<br>出版社:'.$publish;
}
//重寫父類的showInfo方法
public function showInfo()
{
$str = parent::showInfo();
$str .= $this->author;
$str .= $this->publish;
echo $str;
}
}
//建立手機類
$pro = new Mobile('iphone8',8888,'蘋果','美國');
$pro->showInfo();
echo "<hr>";
//建立圖書類
$book = new Book('《你知道張三嗎》',199,'李四','中國');
$book->showInfo();
結果如下:
圖片.png
四、最終類和最終方法
概述:
1)Final關鍵字修飾的類,就是最終類;
2)Final關鍵字修飾的方法,就是最終方法;
3)最終類:該類只能例項化,不能被繼承。該類十分完善了,不需要升級和擴充套件。
4)最終方法:該方法可以被繼承,但不能重寫。該方法十分完善了,不需要重寫了。
五、抽象類和抽象方法
1、概述
1)abstract關鍵字修飾的類,就是抽象類;
2)abstract關鍵字修飾的方法,就是抽象方法;
3)抽象類:該類不能直接例項化,必須先繼承後再例項化。常用在基礎類。
4)抽象方法:方法必須先繼承後重寫。
5)抽象方法就是方法的命名規範、命名規則,也可以理解為一種監督機制。
6)所有的抽象方法都必須重寫,少一個都不行。
7)抽象方法沒有方法體,必須在子類重寫後,再定義方法體。
8)如果一類中有一個抽象方法,該類必須是抽象類。
9)抽象方法許可權不能是private,因為要先繼承再重寫。
10)在PHP7中,抽象方法可以是成員方法,也可以是靜態方法。
11)抽象類中,可以包含其它成員:常量、成員屬性、成員方法、靜態屬性、靜態方法。
示例:
//定義抽象類
abstract class Shop
{
//定義抽象方法:方法的目錄大綱、監督機制
abstract public static function showInfo($name,$price);
abstract public function readMe();
}
//定義最終的圖書類
final class Book extends Shop
{
//重寫showInfo方法
public static function showInfo($name,$price)
{
echo __METHOD__."<br>";
}
//重寫readMe方法
public function readMe()
{
echo __METHOD__;
}
}
//建立圖書類物件
$obj = new Book();
//PHP7中也可以通過物件呼叫靜態方法
$obj->showInfo('moumou',20);
$obj->readMe();
結果如下: