
批改狀態(tài):合格
老師批語(yǔ):
面向?qū)ο缶褪前焉钪幸鉀Q的問(wèn)題都用對(duì)象的方式進(jìn)行存儲(chǔ):把所有的數(shù)據(jù)用屬性、方法表現(xiàn)出來(lái)。對(duì)象之間的互動(dòng)是通過(guò)方法的調(diào)用完成互動(dòng)。
class User
{
// 成員屬性
public $name;
private $salary;
protected $age;
public function __construct($salary, $age)
{
// $this代表本對(duì)象
$this->salary = $salary;
$this->age = $age;
}
// 成員方法
public function salary()
{
return $this->salary;
}
}
對(duì)象:一個(gè)類(lèi)的實(shí)例(Instance)
類(lèi)的實(shí)例化為對(duì)象時(shí)使用關(guān)鍵字new,new之后緊跟類(lèi)的名稱(chēng)和一對(duì)圓括號(hào)
->
符號(hào)來(lái)訪問(wèn)
$name = '滅絕';
$salary = 20000;
$age = 18;
// new 實(shí)例化 得到對(duì)象引用
$mj = new User($salary, $age);
// 訪問(wèn)對(duì)象的屬性和方法
$mj->name = $name;
echo $mj->name; // 滅絕
echo $mj->salary(); // 20000
對(duì)象的屬性和方法有三種訪問(wèn)權(quán)限:
public是公有的類(lèi)成員,可以在任何地方被訪問(wèn),可以被類(lèi)以及子類(lèi)或者對(duì)象都可以訪問(wèn)
class User1
{
public $name;
public function sayHello()
{
echo "Hello " . $this->name;
}
}
$mj = new User1();
$mj->name = '滅絕';
echo $mj->name; // 滅絕
echo $mj->sayHello(); //Hello 滅絕
注意:盡量不要使用公共屬性,因?yàn)橹苯釉L問(wèn)公共屬性不能強(qiáng)制性地檢驗(yàn)數(shù)據(jù)有效性。例如,無(wú)法阻止用戶給 name 這樣賦值:$mj->name = ‘12345’;,解決方法:將屬性設(shè)為私有屬性,然后定義公共方法來(lái)調(diào)用是由屬性。
private私有的類(lèi)成員,只能被自身訪問(wèn),不能被子類(lèi)繼承,也不能被對(duì)象訪問(wèn),只能在自身通過(guò)封裝讓外界訪問(wèn)(例如在類(lèi)里面定義一個(gè)公開(kāi)方法來(lái)調(diào)用私有屬性);
class User
{
private $name;
public function setName($name)
{
if ($this->validateName($name)){
$this->name = $name;
} else {
echo "name 格式有誤!";
}
}
public function getName(){
echo $this->name;
}
// 數(shù)據(jù)驗(yàn)證方法,僅對(duì)象內(nèi)部可見(jiàn),外部無(wú)法訪問(wèn)
private function validateName($name){
if ($name == '' || is_numeric($name)){
return false;
} else if (strlen($name) < 2 || strlen($name) > 8){
return false;
} else {
return true;
}
}
}
$mj = new User();
$mj->setName('滅絕');
$mj->getName(); // 滅絕
protected 受保護(hù)的類(lèi)成員,與 private 類(lèi)似,區(qū)別是可以被子類(lèi)繼承,可以被其自身以及繼承的子類(lèi)訪問(wèn),但是不能被對(duì)象訪問(wèn),只能通過(guò)封裝的方式讓對(duì)象訪問(wèn)
構(gòu)造方法可以在對(duì)象實(shí)例化時(shí)自動(dòng)運(yùn)行,作用是:1,創(chuàng)建實(shí)例的初始化狀態(tài);2,可以給私有/受保護(hù)的屬性初始化賦值。
構(gòu)造方法必須是公共方法(public)。
定義構(gòu)造方法關(guān)鍵字:__construct
class User
{
// 成員屬性
public $name;
private $salary;
protected $age;
public function __construct($salary, $age)
{
// $this代表本對(duì)象
$this->salary = $salary;
$this->age = $age;
}
// 成員方法
public function salary()
{
return $this->salary;
}
}
// 實(shí)例化時(shí)自動(dòng)調(diào)用構(gòu)造方法,將傳入的參數(shù)賦值給屬性 $salary, $age
$mj = new User($salary, $age);
// 屬性 $name 沒(méi)有在構(gòu)造方法中賦值,需要手動(dòng)賦值
$mj->name = $name;
繼承的好處:
子類(lèi):
// 父類(lèi)
class Product
{
public $name;
protected $price;
protected $num;
public function __construct($name, $price, $num)
{
$this->name = $name;
$this->price = $price;
$this->num = $num;
}
// 普通方法
public function show()
{
// 特殊的對(duì)象引用 完成對(duì)象成員間的互相訪問(wèn)
// 注意:界定符結(jié)尾標(biāo)記必須頂行寫(xiě),前面不能有任何輸出,否則出錯(cuò)!
// 界定符結(jié)尾標(biāo)記后面也不能有注釋
return <<<SHOW
1. 品名:$this->name
2. 價(jià)格:$this->price
3. 數(shù)量:$this->num
SHOW;
}
}
// 子類(lèi)
class Son extends Product
{
// 擴(kuò)展
public $brand;
// overwrite 重寫(xiě)
public function __construct($name, $price, $num, $brand)
{
// parent:: 調(diào)用父類(lèi)成員
parent::__construct($name, $price, $num);
$this->brand = $brand;
}
// 重寫(xiě)show方法
public function show()
{
return <<<SHOW
1. 品名:$this->name
2. 價(jià)格:$this->price
3. 數(shù)量:$this->num
4. 品牌:$this->brand
SHOW;
}
// 功能擴(kuò)展
public function total()
{
return "$this->name,數(shù)量為{$this->num},總計(jì)" . ($this->price * $this->num) . '元';
}
}
// 子類(lèi)實(shí)例化及調(diào)用成員
$son1 = new Son('四件套', 289, 400, '法系');
echo $son1->brand; // 法系
echo $son1->show(); // 1. 品名:四件套 2. 價(jià)格:289 3. 數(shù)量:400 4. 品牌:法系
echo $son1->total(); // 四件套,數(shù)量為400,總計(jì)115600元
class View
{
/**
* 模板變量
*/
protected $data = [];
// !當(dāng)訪問(wèn)當(dāng)前環(huán)境下未定義或不可訪問(wèn)的類(lèi)屬性時(shí) ,重載方法__get會(huì)被調(diào)用。
public function __get($name)
{
return $this->data[$name];
}
// !當(dāng)給當(dāng)前環(huán)境下未定義或不可訪問(wèn)的類(lèi)屬性賦值時(shí) ,重載方法__set會(huì)被調(diào)用。
public function __set($name, $value)
{
$this->data[$name] = $value;
}
// 自定義的賦值方法優(yōu)先級(jí)大于 __set
public function assign($name, $value = null)
{
if (is_array($name)) {
// array_merge() 將一個(gè)或多個(gè)數(shù)組中的值附加在前一個(gè)數(shù)組的后面。返回作為結(jié)果的數(shù)組
$this->data = array_merge($this->data, $name);
} else {
$this->data[$name] = $value;
}
return $this;
}
// !當(dāng)訪問(wèn)當(dāng)前環(huán)境下未定義或不可訪問(wèn)的類(lèi)普通方法時(shí) ,重載方法__call會(huì)被調(diào)用。
public function __call($name, $args)
{
if ($name == 'show') {
var_dump($this->data);
} else if ($name == 'sum') {
return array_sum($args);
} else {
echo '沒(méi)有這個(gè)方法';
}
}
}
$v = new View;
// 調(diào)用 __set 方法,給未定義屬性賦值
$v->username = 'peter';
// 調(diào)用 __get 方法,訪問(wèn)未定義屬性
echo $v->username; // peter
// 自定義的賦值方法優(yōu)先級(jí)大于 __set
$v->assign('username', 'admin');
echo $v->username; // admin
// 調(diào)用 __call 方法,訪問(wèn)未定義方法
$v->hello(); // 沒(méi)有這個(gè)方法
// show()、sum() 方法不可以直接訪問(wèn),通過(guò) __call 方法訪問(wèn)
$v->show(); // array(1) { ["username"]=> string(5) "admin" }
echo $v->sum(10, 20, 60); // 90
// 通過(guò)回調(diào)方法訪問(wèn) __call 方法
echo call_user_func([$v, 'sum'], 10, 20, 40); // 70
echo call_user_func_array([$v, 'sum'], [10, 20, 80]); // 110
定義類(lèi)加載器文件 autoload.php
// autoload.php
spl_autoload_register(function ($className) {
$classFile = __DIR__ . DS . 'class' . DS . $className . '.php';
if (is_file($classFile) && file_exists($classFile)) require $classFile;
});
在頁(yè)面引入加載器,不用一個(gè)一個(gè) require 所需的 class 文件
const DS = DIRECTORY_SEPARATOR;
require __DIR__ . DS . 'autoload.php';
// 接下來(lái)用到的類(lèi)都會(huì)自動(dòng)加載
$mj = new User($salary, $age);
$i = new Product('iphone 12 promax', 6000, 12);
$son1 = new Son('四件套', 289, 400, '法系');
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號(hào)
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)