1. 程式人生 > >PHP類的封裝性、繼承性和多型性

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

圖片.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

圖片.png

5、parent關鍵字

1)self代表當前類,parent代表父類。
2)self和parent可以存在於所有方法(成員方法和靜態方法)中。
3)self用來呼叫本類的內容,包括:類常量、靜態屬性、靜態方法、成員方法;
4)parent用來呼叫父類的內容,包括:類常量、靜態屬性、靜態方法、成員方法;
5)self和parent都使用範圍解析符"::"來呼叫其它內容。也可以叫靜態化呼叫方式。

6)語法:parent::類常量 | 靜態屬性 | 靜態方法 | 成員方法圖片.png

圖片.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

圖片.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();

結果如下:

圖片.png