本篇博客源自博主在PHP中文網上寫的原文,移到CSDN做個記錄
1.子類
1.1. 簡介
面嚮對象語言的三大特點:封裝、繼承、多態。
-
封裝,也就是把客觀事物封裝成抽象的類,一個類就是一個封裝了數據以及操作這些數據的代碼的邏輯實體。
-
繼承,是指可以讓某個類型的對象獲得另一個類型的對象的屬性的方法,可以使用現有類的所有功能,並在無需重新編寫原來的類的情況下對這些功能進行擴展,而通過繼承創建的新類稱爲“子類”或“派生類”,被繼承的類稱爲“基類”、“父類”或“超類”。
-
多態,是指一個類實例的相同方法在不同情形有不同表現形式。
1.2. php子類的應用場景
-
代碼複用
-
功能擴展
-
方法重寫
1.3. 演示
<?php
class Demo
{
// 屬性(變量)
public $product;
public $price;
// 構造方法
public function __construct($product, $price)
{
$this->product = $product;
$this->price = $price;
}
// 方法(函數)
public function getInfo()
{
return '商品名稱: ' . $this->product.', 商品價格: ' . $this->price;
}
}
// 子類
// 1. 代碼複用
class Sub1 extends Demo
{
// ...
}
$sub1 = new Sub1('iPhone 11', 9800);
echo $sub1->getInfo() . '<hr>';
// 子類
// 2. 功能擴展
class Sub2 extends Demo
{
// 增加一個屬性
public $num; // 數量
// 構造方法
public function __construct($product, $price, $num)
{
// $this->product = $product;
// $this->price = $price;
parent::__construct($product, $price);
$this->num = $num;
}
// 子類中增加一個新方法: 計算總和
public function total()
{
return round($this->price * $this->num, 3);
}
}
$sub2 = new Sub2('電腦', 3980.1234, 13);
echo $sub2->product . '的總價是: '. $sub2->total(). '<hr>';
// 子類
// 3. 方法重寫
class Sub3 extends Sub2
{
// 重寫total()
public function total()
{
$total = parent::total();
// 設置折扣率
switch (true)
{
case ($total > 20000 && $total < 40000):
$discountRate = 0.88;
break;
case ($total >= 40000 && $total < 60000):
$discountRate = 0.78;
break;
case ($total >= 60000):
$discountRate = 0.68;
break;
default:
// 小於或等於2000,不打折
$discountRate = 1;
}
// 打折後的價格
$discountPrice = round($total*$discountRate, 2);
if ($discountRate < 1) {
$discountPrice=$discountPrice . '元, <span style="color: red">('. $discountRate.'折)</span>';
}
// 返回折扣價
return $discountPrice;
}
}
$sub3 = new Sub3('電腦', 3980, 13);
$sub3 = new Sub3('電腦', 3980, 33);
echo '折扣價是: ' . $sub3->total();
?>
2.訪問限制符
2.1 php的類成員訪問限制符有:
-
public(公共的、默認) :該成員能被外部代碼訪問和操作;
-
protected(受保護的): 對於類內部所有成員都可見,對類外部不允許訪問;
-
private(私有的):只允許該類的子類進行訪問;
分別用在類的屬性和方法上,用來修飾類成員的訪問權限。
2.2. 演示:
<?php
// 訪問控制符:
// public : 類中,類外均可訪問, 子類中也可以訪問
// protected: 類中,類外不可訪問, 但是子類中可以訪問
// private: 只允許在類中, 類外, 子類中不可訪問
class Demo {
// 類中成員: 屬性, 方法
// 成員屬性, 成員方法
// 對象屬性: 需要使用類的實例進行訪問的成員屬性
public $name; // 姓名
protected $position; // 職位
private $salary; // 工資
protected $department; // 部門
// 構造方法
public function __construct($name, $position, $salary, $department) {
$this->name = $name;
$this->position = $position;
$this->salary = $salary;
$this->department = $department;
}
// 職位訪問器/方法/函數
public function getPosition() {
return $this->department === '培訓部' ? $this->position : '無權查看';
}
// 工資訪問器/方法/函數
public function getSalary() {
// 工資 只允許財務部的人看
return $this->department === '財務部' ? $this->salary : '無權查看';
}
// 部門獲取器/方法/函數
public function getDepartment() {
return $this->department;
}
}
$obj = new Demo('朱老師', '講師', 8888, '培訓部');
echo 'name = ' . $obj->name, '<br>';
// echo 'position = ' . $obj->position, '<br>'; // 會報錯,protected 變量,類外部不允許訪問
// echo 'salary = ' . $obj->salary; // private,會報錯不允許訪問
echo $obj->getPosition(), '<br>';
echo $obj->getSalary(), '<br>';
echo $obj->getDepartment(), '<hr>';
class Sub extends Demo {
public function display() {
echo $this->name . '<br>'; // public
echo $this->position . '<br>'; // protected
// echo $this->salary . '<br>'; // private,這裏會報錯,無法訪問
}
}
$sub = new Sub('歐陽克', '講師', 9999, '培訓部');
$sub->display();
echo '<br>';