摘要:接口可以使用常量,叫接口常量,和類的常量使用方法相同類可以同時繼承多個接口使用接口常量抽象類不能被實例化。繼承抽象類,子類必須實現父類中所有的抽象方法。
訪問控制
屬性和方法的訪問控制(可見標識):
public 任何地方
private 類自身
protected 類自身,自子類及自父類
this 可以理解為這個類的一個實例
selfself 代表類本身
__construct實例化時就會自動執行
public function __construct() {}
當對象對銷毀時自動執行
public function __destruct(){}
定義合不可改變
const ONE = 1
const TWO = self::ONE + 1;
可以在類外部調用
Class::Two
parent代表父類
public function __construct(){ parent::__construct();}
final class Dad(){} 加到類定義前面表示Dad類不想被繼承
class Dad(){ final public function run(){} // 加到方法聲明前面,表示方法不想被子類重寫 }namespace
namespace必須放在代碼文件的第一行
受命名空間影響的類型:類(包括抽像類,traits)、接口、函數和常量。
當沒有使用namespace關鍵字指定命名空間時,當前腳本是存在于全局命名空間的。用表示。Class1
類全在指定的命名空間去查找,沒找到則拋出錯誤。
函數與常量,在指定命名空間查找,沒找到則到全局命名空間查找,還沒打到則拋錯。
ns1 s2fn()
常量define定義的常量是全局的,不受命名空間影響。
const定義的常量受命名空間影響。
namespace ns1 s2; const ONE = 1; echo ns1 s2ONE;use 導入類
用use導入命名空間下的類
use ns1
s2class1;
用as重命名導入的類
use ns1
s2class1 as class2;
use function ns1 s2fn as fn1;
導入常量use const ns1 s2ONE;
自動加載 __autoloadfunction __autoload($className){ require $className . ".php";}spl_autoload_register 傳匿名函數
spl_autoload_register(function($className){ require $className . ".php"; });傳函數名
function test($className){ require $className . ".php"; } spl_autoload_register("test");傳類
class Momo { function autoload($className) { require $className . ".php"; } } spl_autoload_register([new Momo, "autoload"]);static
聲明靜態屬性和靜態方法,不經過實例化,通過類名即可調用。
class Person() { public static $hand = "手"; public static function run() { echo "running..."; } } echo Person::$hand; Person::run();
類內部調用靜態屬性和靜態方法用self關鍵字
echo self::$hand; self::run();
調用父類的靜態屬性和靜態方法用parent關鍵字
echo parent::$hand; parent::run();
后期靜態綁定class A { public static function who() { echo "A類的who方法"; } public static function test1() { self::who(); } public static function test2() { static::who(); } } class B extends A { public static function who() { echo "B類的who方法"; } } B::test1(); // test1內部用的self,調用的是自身(A類)的靜態方法 B::test2(); // 后期綁定。內部用static,根據后期的調用環境確定,調用的是B類的靜態方法魔術方法 __set
class Test { private $name = ""; public function __set($var, $val) { // 對$val進行數據處理 $this->$var = $val; } } $test = new Test(); $test->name = "tom"; // 賦值tom__get
class Test { private $name = "jack"; public function __get($var) { return $this->$var; } } $test = new Test(); echo $test->name; // jack__isset
用于檢測私有屬性是否存在
class Test { private $name = "mary"; public function __isset($var) { return isset($this->$var); } } $test = new Test(); var_dump($test->name); // 如果不設置__isset,返回false,設置后返回true__unset
用于刪除私有屬性
class Test { private $name = "Levi"; public function __unset($var) { unset() } } $test = new Test; unset($test->name); // 會觸發__unset__call
避免調用一個不存在的方法時產生錯誤,當調用的方法不存在時,__call方法會自動調用
class Test { public function __call($fn_name, $fn_arguments) { echo $fn_name; print_r($fn_arguments); } } $test = new Test(); $test->go(1, "ok"); // 自動調用`__call`方法,打印出函數名和參數數組__callStatic
同__call類似
避免調用一個不存在的靜態方法
class Test { public static function __callStatic($fn_name, $fn_arguments) { echo $fn_name; print_r($fn_arguments); } } // `__callStatic` 必須聲明為靜態方法 Test::go(1, "ok");__invoke
當對象以函數的形式調用的時候,自動調用__invoke方法
class Test { public function __invoke($args) { return $args; } } $test = new Test(); $test("go....."); // 運行__invoke__toString
當打印對象是會調用__toString方法
class Test { public function __toString() { return "Hello world!"; } } $test = new Test; echo $test; // 輸出 Hello world!對象復制 淺拷貝
比較省內存,對象的拷貝默認是淺拷貝。
$a = new Test(); $b = $a; // 淺拷貝。傳址。改變$b。$a也會改變。
對象的復制是淺拷貝的。傳址。
普通變量的拷貝是深拷貝的。傳值。
$a = new Test(); $b = clone $a; // 深拷貝。改變$b,不會改變$a。__clone
當使用clone關鍵字時,自動調用__clone方法
class Test { public $obj = null; public function __clone() { $this->obj = clone $this->obj; } } class Person { public $sex = 0; } $a = new Test; $a->obj = new Person; $b = clone $a; // 觸發`__clone` 對obj進行深拷貝 $b->obj->sex = 1; // $b中的obj對象改變了。而$a中的obj對象沒變。類型約束
class A { public function go() { echo "go ....."; } } function test(A $a) { $a->go(); } test(new A());Trait
單繼承語言PHP的代碼復用機制。
Trait Bt { public function atest() { echo "Hello "; } public function btest() { echo "world"; } public function ab() { $this->atest(); $this->btest(); } } class Test { use Bt; // 使用Bt Trait,便擁有了Bt所有的方法 } $test = new Test; $test->ab();
繼承多個Trait
Trait A { public $name = "tom"; public function a() { echo "Hello "; } } Trait B { public function b() { echo "world "; } } class Test { use A,B; public function c() { echo $this->name; } } $test = new Test; $test->a(); $test->b(); $test->c(); // Hello world tom
Trait 支持嵌套
Trait A{} Trait B{} Trait C { use A,B; } Class Test { use C; }interface
接口是類的模板。在接口中只定義需要實現的空方法,這些方法在接口中不做具體實現。
接口是不能被實例化的。
Interface Person { public function eat(); public function sleep(); } class man implements Person { public function eat() { echo "eating..."; } public function sleep() { echo "sleeping..."; } } class L { public static function factory(Person $user) // 用接口作類型約束 { return $user; } } $user = L::factory(new Man()); $user->eat(); $user->sleep();
接口可以繼承接口。
接口可以繼承多個接口。
接口可以使用常量,叫接口常量,和類的常量使用方法相同
Interface Ia { const ONE = 1; public function eat(); } Interface Ib { public function sleep(); } Interface AB extends Ia,Ib {} // class Test implements Ia,Ib 類可以同時繼承多個接口 class Test implements AB { public function eat() { echo "eating..."; } public function sleep() { echo "sleeping..."; } } $test = new Test; $test->eat(); $test->sleep(); echo Ia::ONE; // 使用接口常量abstract
抽象類不能被實例化。
如果至少有一個方法被聲明為抽象的,那么這個類必須被聲明為抽象的。
抽象方法只能聲明,不能有具體功能實現。
抽象類可以有被實現的的方法。
繼承抽象類,子類必須實現父類中所有的抽象方法。
這些方法的訪問控制必須和父類一樣,或者更寬松,不能比父類更嚴格。
方法的調用方式也必須匹配。類型和參數數量必須一致,但子類可以定義父類中不存在的可選參數。
abstract AB { public function run() { echo "running..."; } abstract public function eat(); abstract public function sleep(); } class Test extends AB { public function eat() { echo "eating..."; } public function sleep($time = "21:00 PM") // 可以定義父類方法中不存在的可選參數 { echo "sleep @ " . $time; } }單例模式
只能被實例化一次,節省內存空間
class Test { private static $instance = null; private function __constrct() {} private function __clone() {} public static function getInstance() { if (!(self::instance instanceof self)) { self::instance = new self(); } return self::instance; } } $test = Test::getInstance(); // 多次調用也只是實例化一次工廠模式
Interface CacheI { public function set($key, $value); public function get($key); public function delete($key); } class Memcache implements CacheI { public function set($key, $value){} public function get($key){} public function delete($ke){} } class Redis implements CacheI { public function set($key, $value){} public function get($key){} public function delete($ke){} } class Cache { public static function factory() { return new Memcache(); // 這里可以是繼承了CacheI接口的任何類,比如Redis } } $cache = Cache::factory(); $cache->set("name", "tom"); $cache->get("name"); $cache->delete("name");
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29698.html
摘要:類與對象基本概念如果在之后跟著的是一個包含有類名的字符串,則該類的一個實例被創建。如果該類屬于一個名字空間,則必須使用其完整名稱。如果一個類被聲明為,則不能被繼承。命名空間通過關鍵字來聲明。 類與對象 基本概念 new:如果在 new 之后跟著的是一個包含有類名的字符串,則該類的一個實例被創建。如果該類屬于一個名字空間,則必須使用其完整名稱。 Example #3 創建一個實例 ...
摘要:抽象類支持抽象類和抽象方法。接口是一種特殊的抽象類,這種抽象類中只包含抽象方法和靜態常量。對抽象類的使用是通過關鍵字。抽象類中可以聲明各種類型成員變量,實現數據的封裝。一個類可以同時實現多個接口,但一個類只能繼承于一個抽象類。 抽象類 php5支持抽象類和抽象方法。類前加 abstract, 此類就成為抽象類,無法被實例化,此類天生就是用來被繼承的,給子類提供了一個類的模板;類方法前加...
摘要:面試專欄正式起更,每周一三五更新,提供最好最優質的面試內容。繼上一篇面試常考內容之面向對象發表后,今天更新面向對象的最后一篇。面向對象的主要特征為封裝繼承多態。為了提高內聚性減少引起變化,單一原則是低耦合高內聚的面向原則上的引申。 PHP面試專欄正式起更,每周一、三、五更新,提供最好最優質的PHP面試內容。繼上一篇PHP面試常考內容之面向對象(2)發表后,今天更新面向對象的最后一篇(3...
摘要:同時也可以用來實現委托,委托是指一個對象轉發一個請求給另一個對象,把請求的處理委托給另一個對象。但在繼承是父類與子類的關系是固定的,而使用委托可以在運行時改變使用的對象,委托比繼承具有更大的靈活性。 PHP中要實現類似于Java中的getter和setter有多種方法,比較常用的有: 直接箭頭->調用屬性(最常用),不管有沒有聲明這個屬性,都可以使用,但會報Notice級別的錯誤 $d...
閱讀 2345·2021-11-11 16:54
閱讀 2596·2021-09-26 09:47
閱讀 3978·2021-09-08 09:36
閱讀 2727·2021-07-25 21:37
閱讀 927·2019-08-30 15:54
閱讀 2540·2019-08-30 14:22
閱讀 3245·2019-08-30 13:57
閱讀 2558·2019-08-29 17:17