-
<?php
use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Compare;
/**
?* 訪問控制
?* public 公有
?* private 私有 ?只能在類內部使用
?* protected
?* 類的屬性和方法
?* this 類的一個實例
?* 類常量
?* ----繼承----
?* 當父類的方法是私有的private的時候,子類是不能調用的,內部是可以訪問的
?* 當父類的方法是受保護的protected的時候,子類是可以訪問的
?* 當子類的方法與父類的方法相同的時候, 子類覆蓋父類方法
?* 當子類沒有構造方法時, 直接調用父類的構造方法
?* 當子類和父類都有構造方法時, 子類調用其本身的構造方法,當想調用父類的構造方法時使用:parent::construct();
?* ---final 關鍵字---
?* final class Dad {} 類加上final 關鍵字后, 類不能被繼承
?* final function Name(){} ?父類的方法加上final關鍵字后,該方法在子類時不能被重寫的
?* --- 命名空間---
?* namespace venter\session
?* namespace test
?* ---define----
?* define 定義常量是全局的
?* --- const 定義常量----
?* ---自動加載類 autoload 用的少 基本都在使用 spl_autoload_register()----
?* ---static 關鍵字---
?* 當屬性和方法被定義為static的時候, 這個屬性和方法就屬于類的屬性和方法, 可以直接調用, 不需要實例化
?* ?----對象復制---
?* 在php中對象的拷貝是淺拷貝, 改變地址
?*
?* --- 接口---
?* 接口是類的模板,類是對象的模板
?* interface Person{
?* }
?*
?**/
?class Computer{
? ? ?//屬性
? ? public $cpu=5000;
? ? public $mainboard ='huashuo';
? ? private $ht="512";
? ? const ONE =1;
? ? const TWO= self::ONE+1;
? ? const THREE = self::TWO+1;
? ? //構造方法 ?實例化的時候調用
? ? public function __construct()
? ? {
? ? ? ?
? ? }
? ? function __autoload($name){
? ? ? ? require $name.".php";
? ? }
? ? //方法
? ? public function game($gamename){
? ? ? ? if($this->hdSize<1024){
? ? ? ? ? ? echo '內存太小';
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? return true;
? ? ? ?
? ? ? ?
? ? }
? ? public function job($jobName='write code'){
? ? ? ? $this->game("ddd");
? ? }
? ? public function hdSize(){
? ? ? ? $this->ht;
? ? }
? ? //析構方法
? ? public function __destruct()
? ? {
? ? ? ?
? ? }
?}
?
// ?var_dump(Computer::THREE);
// ?$computer = new Computer();
// ?$computer->job();
?class Person{
? ? ?public static $hand ="手";
? ? ?public static $foot = "腳";
? ? ?static function getCount(){
? ? ? ? ?return self::$foot;
? ? ?}
?}
echo Person::getCount();
class A{
? ? public static function who(){
? ? ? ? echo "A類的方法";
? ? }
? ? public static function test(){
? ? ? ? //self::who() ; //父類本身的who方法
? ? ? ? static::who(); // static 自動判斷,是類A還是類B, 后期綁定
? ? }
}
class B extends A{
? ? public static function who(){
? ? ? ? echo "B類的方法";
? ? }
}
echo B::test(); ?// 此時輸出 “B類的方法” ?
class Test{
? ? private $abc="";
? ? public $testi;
? ? public function __set($var,$val){
? ? ? ? $this->var=$val;
? ? }
? ? public function __get($var){
? ? ? ? return $this->var;
? ? }
? ? //調用的方法不存在時, 不會報錯 兩個參數, 一個方法名, 一個參數名
? ? public function __call($func,$var){
? ? ? ? ? ? var_dump($var) ;
? ? }
? ? //靜態方法未定時,調用不會報錯 ? $test::goes("r","d","4");
? ? public static function __callStatic($name, $arguments)
? ? {
? ? ? ? var_dump($arguments);
? ? }
? ? ?public function __toString(){
? ? ? ? ?return $this->test;
? ? ?}
}
$test = ?new Test();
$test->abc ='abcsss';
$test->go("q","d","dd"); ?//已數組的方式傳參數 go方法沒有定義,不會報錯
$test::goes("r","d","4"); // 該方法未定義直接調用, 不會報錯,
echo $test; ? //echo 輸出對象不會報錯, 因為定義了 __toString()魔術方法
var_dump($test->abc);
//接口-----------------------------------------------------------
interface Persons{
? ? public function eat();
? ? public function sleep();
}
class Woman implements Persons{
? ? public function eat(){
? ? ? ? echo "eat fruit";
? ? }
? ? public function sleep(){
? ? ? ? echo 'sleep early';
? ? }
}
class Man implements Persons{
? ? public function eat(){
? ? ? ? echo "eat fruit less";
? ? }
? ? public function sleep(){
? ? ? ? echo 'stay up';
? ? }
}
class L {
?public static function factory(Persons $user){
? ? return $user;
?}
}
$result = L::factory(new Man());
$result->eat();
$result->sleep();
//接口 繼承--------------------------------------------------------------------------
interface ai{
? ? const abc="hhhh";
? ? public function a();
}
interface bi{
? ? public function b();
}
interface ab extends ai,bi{
}
class Test4 implements ab{
? ? public function a(){
? ? ? ? echo "aaaaaaaaa";
? ? }
? ? public function b(){
? ? ? ? echo "bbbbbbb";
? ? }
}
$dd = new Test4();
$dd->a();
$dd->b();
echo (ai::abc);
// 抽象類abstract、
abstract class ABC {
? ? public function holiday(){
? ? ? ? echo "wait";
? ? }
? ? public function sleep(){
? ? } ?
? ? public function eat(){
? ? }
}
class ABB extends ABC{
? ? public function sleep(){
? ? ? ? echo "Yes";
? ? }
? ? public function eat(){
? ? ? ? $this->holiday();
? ? ? ? echo "No";
? ? }
}
$aaa = new ABB();
$aaa->eat();
$aaa->sleep();
//------單例模式和工廠模式----------
//單例模式確保類只能有一個實例 節省空間
class TestAB{
? ? private static $_instance =null;
? ? private function __construct()
? ? {
? ? ? ?
? ? }
? ? private function __clone(){
? ? }
? ? public static function getInstance(){
? ? ? ? if(!(self::$_instance instanceof self)){
? ? ? ? ? ? self::$_instance =new self();
? ? ? ? }
? ? ? ? return self::$_instance;
? ? }
}
$nn = TestAB::getInstance();//實例化兩次,但是只開辟一次空間 ?兩個變量值相同
$nn2 = TestAB::getInstance();
print_r($nn) ;
print_r($nn2) ;
//------- 工廠模式
//
class Memcache{
? ? public function set(){
? ? }
? ? public function get(){
? ? }
? ? public function delete(){
? ? }
}
class Cache{
? ? public static function factory(){
? ? ? ? // 文檔中多數運用Memcache類時, 假如因為當前需要,改為redis ,需要使用工廠模式
? ? ? ? return new Memcache();
? ? }
}
//直接把Memcache 替換為redis 即可, 其他代碼部分不需要更改
$cache = cache::factory();
$cache->set();
查看全部 -
? 在php中繼承的特點是只支持單繼承,即一個子類只能繼承一個父類, 去獲得父類中的方法。但從php5.4開始有trait概念,一個類可以通過use關鍵字引入多個trait的方法,用trait解決了單繼承的問題。
查看全部 -
類型約束有int,string,array,float,bool等。但類也可以作為類型約束的類型之一,如圖test(A $a)指的是$a必須是類A的對象,否則會報錯。
查看全部 -
淺拷貝:對象賦值$b=$a,2個對象指向同一塊內存地址,值發生改變會互相影響。淺拷貝比較省內存。
深拷貝:用clone關鍵字,會產生一塊新的內存存儲對象。clone后相當于有兩個值相同的不同的對象。若clone的原對象里有對象屬性如$a->obj,由于對象復制默認是淺拷貝,則要用到__clone魔術方法定義對象屬性為深拷貝。這樣$a->obj->sex才不受$b->obj->sex影響。
查看全部 -
self::who()和static::who()的區別在于self指的本類,即父類A,而static會根據代碼實際情況判斷指的是B類。
查看全部 -
static關鍵字
當屬性和方法加上static關鍵字后,屬性和方法就是類的,可以直接通過類名進行調用,無需實例化。么 當給一個屬性加上static關鍵字,那么這個屬性變成了類屬性,不需要實例化類(獲得對象)就可以直接用類名進行調用。如Person::$foot;方法同理如Person::work();
查看全部 -
命名空間+類名 = 類文件路徑.
用spl_autoload_register()替換字符串后自動加載類文件
查看全部 -
命名空間和全局空間
????1. 在全局空間中引用命名空間的類,用use關鍵字引入命名空間的類,as起別名。若引入函數則為use function venter\session\iLikeImooc;引入常量則為use const venter\IMOOC;
????2.在命名空間中引用全局空間的類,若為namespace venter,即命名空間為venter,如new Test();類默認為venter\Test();找不到會報錯,在類前加反斜杠new \Test();則為找到全局空間的Test類。函數和常量會先在命名空間中找,找不到會去全局找。
查看全部 -
extends查看全部
-
外部想要對私有屬性進行讀取和修改。
<?php class?Test { ????private?$abc?=?''; ????public?function?setAbc($val)????//修改 ????{ ?????????$this->abc?=?$val;???????? ?????} ????? ?????public?function?getAbc()?????//讀取 ?????{ ??????????return?$this->abc; ??????} } $test?=?new?Test(); $test?=?setAbc('hahaha');????//hahaha賦給參數$val var_dump($test->getAbc());?????//打印出:string(6)"hahaha"
若有多個私有屬性要被外部訪問,上述就不行了,所以有了兩個魔術方法:__set 和 __get 。如:
<?php class?Test { ????private?$abc?=?''; ????private?$cba?=?''; ????public?function?__set($var,$val)????//修改。?__set(屬性名,屬性值) ????{ ?????????$this->$var?=?$val;???????? ?????} ????? ?????public?function?__get($var)?????//讀取。??__get(屬性名) ?????{ ??????????return?$this->$var; ??????} } $test?=?new?Test(); $test->abc?=?'hahaha';????//當給私有屬性賦值時,會默認自動地調用__set方法,如果類里沒有__set方法,就會報錯 var_dump($test->abc);?????//打印出:string(6)"hahaha"
魔術方法 __isset 用于檢測私有屬性是否存在。
<?php class?Test { ????private?$abc?=?'abc'; ???? ????public?function?__isset($var) ????{ ????????return?isset($this->$var)?true:false; ?????} } $test?=?new?Test(); var_dump(isset($test->abc));????//打印出:bool(true)
魔術方法__unset 刪除
<?php class?Test { ????private?$abc?=?'aaa'; ???? ????public?function?__unset($var) ????{ ????????unset($this->$var); ?????} } $test?=?new?Test(); unset($test->abc);
為避免要調用的方法不存在,用魔術方法 __call? 當被調用的方法不存在時,__call 會自動被調用。如:
<?php class?Test { ????public?function?__call($func,$arguments)?????//__call(方法名,參數) ????{ ????????echo($func?.?"<br/>"); ????????print_r($arguments); ?????} } $test?=?new?Test(); $test->go(1,'ok');?????//結果為:go ????????????????????????//???????Array(?[0]?=>1?[1]?=>?ok?)
當靜態方法不存在時,魔術方法__callStatic 會被自動調用。如:
<?php class?Test { ????public?static?function?__callStatic($method,$arg)????//要加static關鍵字???__callStatic(方法名,參數) ????{ ????????echo($method?.?"<br/>"); ????????print_r($arg); ?????} } Test::go(1,'ok');??????//結果為:go ????????????????????????//???????Array(?[0]?=>1?[1]?=>?ok?)
當對象以函數的方式被調用時,魔術方法__invoke會自動被調用。
<?php class?Test { ?????public?function?__invoke($arg) ?????{ ?????????var_dump($arg);???? ??????} } $test?=?new?Test(); $test('go....');??//這就是對象以函數的方式被調用???結果為:string(6)"go...."
當對象被打印時,魔術方法__toString()?會自動被調用。
<?php class?Test { ?????public?function?__toString() ?????{ ?????????return?"hello.....";???? ??????} } $test?=?new?Test(); echo($test);?????//結果為:hello......
查看全部 -
<?php class?A?{???? ?????public?static?function?who()??? ?????{???????? ?????????echo?"AAA";???? ??????}???? ??????public?static?function?test()???? ??????{???????? ????????????static::who();??????//之后的結果為BBB,若用self::who(),則結果為AAA???? ???????}????????????????????????//因為子類B調用父類的test方法,又調用who方法,子類父類都有who方法,用static是調用子類的who方法,用self是調用父類(也就是self所在類的)who方法 } //子類 class?B?extends?A?{???? ????public?static?function?who()???? ????{???????? ?????????echo?"BBB";???? ?????} } B::test();???//因為這里是B,所以父類A和子類B都有who方法我們也要調用子類B的who方法,
查看全部 -
imooc.php:
<?php class?Imooc { ????public?function?nice() ????{ ????????echo?"imooc?nice"; ?????} }
main.php:
<?php function?__autoload($className)????//__autoload()是內置函數,實現類的自動加載 { ?????require?$className?.?".php";???? ?} ?$imooc?=?new?Imooc(); ?var_dump($imooc);???//結果為:object(Imooc)#1(0){} ? ? ?//__autoload()函數將在以后PHP版本里不再使用,所以用spl_autoload_register()函數 <?php spl_autoload_register(function($className){ ?????require?$className?.?".php"; }); $imooc?=?new?Imooc(); var_dump($imooc);??????//結果為:object(Imooc)#1(0){} //還可以: ?<?php ?function?test($className){ ??????require?$className?.?".php"; } spl_autoload_register('test'); $imooc?=?new?Imooc(); var_dump($imooc);??????//結果為:object(Imooc)#1(0){} //若在類里: <?php class?Momo { ????function?haha($className) ????{ ?????????require?$className?.?".php"; ?????} } spl_autoload_register([new?Momo,'haha']); $imooc?=?new?Imooc(); var_dump($imooc);?????//結果為:object(Imooc)#1(0){}
現文件級別如下:
main.php:
<?php spl_autoload_register(function($className){ ?????include?str_replace("\\","/",$className?.".php");????//將\轉換為/,?(兩個\\因為其中一個\是轉義字符)將在網頁上顯示models/Imooc,為了顯示出路徑 }); $imooc?=?new?models\Imooc(); var_dump($imooc);?????//結果為:object(models/Imooc)#2(0){}
Static關鍵字:
當給屬性加上Static關鍵字,該屬性就是類的屬性,而不是對象的,不用實例化這個類,就可以通過類名調用。方法也是可以。如:
<?php class?Person { ????public?static?$hand?=?"手"; ????public?static?$foot?=?"腳"; ???? ????public?static?function?work() ????{ ?????????return?"單純的工作"; ?????} } echo(Person::$foot); echo(Person::work());
<?php class?Person { ????public?$a?=?1; ???? ????public?static?function?work() ????{ ?????????echo?($this->$a);?????//有static關鍵字時不能這樣,會報錯。$this代表的是對象,self是代表的是類 ?????????return?"單純的工作"; ?????} } echo(Person::work());????//會報錯 <?php class?Person { ????public?static?$hand?=?"手"; ????public?static?$foot?=?"腳"; ???? ????public?static?function?work() ????{ ?????????echo(self::$hand);??????//因為是類的方法和屬性,不是對象的,所以用self ?????????return?"單純的工作"; ?????} } echo(Person::work());???//結果為:手單純的工作 //子類 class?Imooc?extends?Person { ????public?function?play() ????{ ????????parent::work();?????//parent代表類 ?????} } $imooc?=?new?Imooc(); echo($imooc->play());????//結果為:手單純的工作
查看全部 -
兩個類的類名相同,會出現錯誤。? ?所以引入了命名空間。
?
和文件中的目錄一樣,同一目錄不存在相同命名的文件,而不同目錄存在相同命名的文件。 命名空間借鑒了這種方法。
php:
<?php namespace?venter;???//用namespace關鍵字,Imooc類和iLikeImooc()函數和IMOOC常量就在venter命名空間下 class?Imooc { ?} function?iLikeImooc(){ ????echo?"i?Like?imooc"; } //曾經用define()定義一個常量,這個不受命名空間影響,所以用const定義常量 const?IMOOC?=?'nice';
2.php:
<?php namespace?venter\session;???//用\表示session是venter下一級, class?Imooc { ?}
main.php:
<?php include?'1.php'; include?'2.php'; var_dump(new?venter\Imooc()); var_dump(new?venter\session\Imooc());??//兩個同名類就都可打印了 venter\iLikeImooc();????//兩個同名函數就可調用了 echo(venter\IMOOC);????//同名常量都可打印出來了
還可以這樣:
main.php:
<?php include?'1.php'; include?'2.php'; use?venter\session\Imooc; var_dump(new?Imooc());????//就不需要這樣一大串var_dump(new?venter\session\Imooc());? use?venter\Imooc?as?Imooc2;?????//另一同名類用as取名為Imooc2 var_dump(new?Imooc2());? use?function?venter\iLikeImooc;????//函數,use后需要有function?,能加as命名 iLikeImooc(); use?const?venter\IMOOC;???//常量,use后要有const var_dump(IMOOC);
當沒有使用namespace來指定當前腳本的命名空間時,則當前腳本存在于全局命名空間。命名空間分兩個,一個是有被指定,一個沒有指定。
3.php:
<?php class?Test1 { } function?Text2() { } const?TEST3?=?'test3';
index.php:
<?php namespace?index; include?'3.php'; var_dump(new?\Text1());????//在此腳本文件有命名空間下,會找此命名空間的類, ????????????????//若是var_dump(new?Text1())因為Text1是3.php是全局空間的類,就會報錯,找不到類。所以Text1前加\ Test2();??//函數和常量在此命名空間下若沒有,會自動在全局空間3.php里找,而類不自動去全局空間找,所以要加\ echo(TEST3);
查看全部 -
被繼承的類叫父類。子類繼承父類的屬性和方法。通過子類擴展了父類的功能,是之前所學的擴展性。
<?php class?Dad { ????public?function?Kungfu() ????{ ????????echo?"降龍十八掌"; ?????} } class?Boy?extends?Dad?????//使用?extends?關鍵字使子類繼承父類 { ?} ? $boy?=?new?Boy(); $boy->Kungfu();????//結果為:降龍十八掌???(子類繼承父類的屬性和方法)
當父類的方法是私有的(private),子類不能調用,只有父類本身類的內部能用。
當父類的方法是受保護的(protected),只能被父類自己和繼承的子類調用,其他類和外部不能調用。
方法名相同時,子類的方法覆蓋父類的方法:
<?php class?Dad { ????public?function?Kungfu() ????{ ????????echo?"降龍十八掌"; ?????} } class?Boy?extends?Dad { ?????public?function?Kungfu()??//方法名相同時,子類的方法覆蓋父類的方法: ?????{ ?????????echo?"凌波微步無影掌"; ??????}???? ?} ? $boy?=?new?Boy(); $boy->Kungfu();????//結果為:凌波微步無影掌
當子類沒有構造方法時,會自動調用父類的構造方法。
當子類有自己的構造方法時,就調用自己的構造方法,而不會調用父類的構造方法。若既想調用父類的構造方法也有子類的,用 parent 關鍵字。如:
<?php class?Dad { ????public?function?__construct() ????{ ????????echo?"dad?dad..."; ?????} ?????public?function?Kungfu() ?????{ ?????????echo?"降龍十八掌"; ??????} } class?Boy?extends?Dad { ????public?function?__construct() ????{ ????????parent::__construct();???//若既想調用父類的構造方法也有子類的,用?parent?關鍵字。 ????????echo?"boy?boy.."; ?????} ?} ? $boy?=?new?Boy(); $boy->Kungfu();????//結果為:dad?dad...boy?boy...降龍十八掌
父類不想被子類繼承,用 final 關鍵字,如:
final?class?Dad
??
父類的某個方法不想被子類繼承,用 final 關鍵字,如:
final?public?function?Kongfu()
查看全部
舉報