**對象是類的實例化結果。類是對象的抽象描述。**
類的定義:
???????? [修飾符] class 類名 [extends 父類] [implements 接口1[,接口2...]]{
?????????????????? ?? 【成員屬性】定義變量??
?????????????????? ?? 【成員方法】定義函數
?????????????????? }
**類前的修飾符:final、abstract**
**常用屬性的修飾符:public、protected、private、static**
**常用的修飾符:public、protected、private、static、abstract、final**
*****
我們在類中調用自己的成員屬性或函數都是使用 $this->調用。
*****
構造方法:__construct(),實例化一個對象第一個自動執行的方法。
析構方法:__destruct();對象被銷毀時最后自動調用的方法.
*****
__get($name):直接輸出對象中的非公有屬性時會自動調用。
```
public function __get($par){
?return $this->$par
}
```
*****
__set($name,$val):直接設置對象中的非公有屬性會自動調用。
```
public function __set($par,$value){
?$this->$par=$value;
}
```
(如果變量沒有在類的內部定義,會添加)
當對未定義的變量調用isset() 或 empty()時,__isset() 會被調用。
非公有對外界都是不可見的,用isset可以判斷存不存在.
當對未定義的變量調用unset()時,__unset() 會被調用。
```
__unset function __unset($par){
?unset($this->$par)
}
```
*****
## 繼承:extends
**繼承:extends,子類會繼承父類的公有,受保護方法。如果子類方法和父類重名則覆蓋。**
1.php只支持單繼承。一個子類只能有一個父類。但一個類可以被多個類繼承。
2.子類繼承父類所有屬性,但私有屬性不能直接訪問,子類可以通過繼承父類的方法來間接訪問父類的私有屬性。
3.通過2可推出子類繼承的方法是引用而不是復制。
4.子類中新增加的屬性和方法叫擴展。子類中與父類同名的屬性是對父類的覆蓋。
5.如果子類的屬性為私有則無法繼承父類的set/get
*****
## parent::
1調用父類被覆蓋的方法
2子類在繼承父類后,子類的構造方法中要先繼承父類的構造方法
```
public function __construct($name,$age,$classid){
? //先構造父類
? parent::_\construct($name,$age);
? $this->classid = $classid;
?}
```
3覆蓋父類的方法(升級)
```
public function getinfo(){
? return parent::getinfo().":".$this->classid;
?}
```
*****
## final修飾符(禁止方法被覆蓋,類被繼承)
1.靜態方法(屬性)調用之前不用實例化類可以直接使用。
類::靜態屬性 ? ?類::靜態方法
2.在類中,不能使用$this來引用靜態變量,而要用self(自己)來引用。
self::$靜態屬性 ?self::靜態方法
3.self在靜態方法中可以調用其他靜態方法和屬性,靜態中不可以調用非靜態($this)
4.在一個類的方法中若沒有$this,默認為靜態
實例化后,靜態方法可以使用對象調用。靜態屬性不行。
`const ConstName="value";`
1.只能修飾成員屬性
2.類內訪問通過self:: ?;內外訪問 類名::常量名
instanceof 檢測當前對象實例是否屬于某一個類的類型
*****
## 單例:
創建類A:
? ? 私有化靜態變量默認為空,(用來存放實例化)。
? ? 私有化構造方法。
? ? 公有靜態方法:
? ? ? ? 判斷私有化靜態變量是否為空
? ? ? ? ? ? 為空則實例化本類賦值給私有化靜態變量
? ? ? ? 返回私有化靜態變量。
? ? 其他方法。。
使用:
? ? $a=類名::公有靜態方法。
? ? $b=類名::公有靜態方法。
```
class A{
?private static $ob=null;
?//私有化構造方法
?private function __construct(){
?}
?public static function makeA(){
? if(empty(self::$ob)){
? ?self::$ob = new A();
? }
? return self::$ob;
?}
?//編寫其他實用方法
?public function add(){
?}
?public function del(){
?}
}
$a1 = A::makeA();
$a2 = A::makeA();
var_dump($a1);
var_dump($a2);
```
*****
## 數組的串行化
(json_encode/json_decode)
$s = json_encode($a); //將數組復合類型轉成json格式
$b = json_decode($s,true); //將json格式轉回數組格式
## 對象的串行化
```
serialize()//串行
unserialize()//反串行
$str = serialize($s);
file_put_contents("ob.txt",$str);
$ob = unserialize($str);
```
__sleep(): 是執行串行化時自動調用的方法,目的是實現資源類型的屬性實關閉操作。
(sleep方法需要返回一個數組,其中數組中的值是串行化時要保留的屬性名)
```
public function __sleep(){
? //關閉資源
? if($this->link){
? ?fclose($this->link);
? ?$this->link=null;
? }
? return array("fname"); //并返回串行時需要保留的屬性名
?}
```
__wakeup():是在執行反串行化時自動調用的方法,目的是實現資源屬性的打開(sleep方法關閉的資源)
```
public function __wakeup(){
? $this->link = fopen($this->fname,"a+");
?}
```
## 對象克隆clone
由于對象屬于引用賦值,所以 =不能用來復制。=相當于起別名。
$a2 = clone $a1;
__toString()直接輸出一個對象時,會自動調用。
__call($name,$arrays)當調用一個不可訪問的方法(未定義或不可見),自動調用
__autoload(類名)
當實例化一個對象時,這個類不存在,則自動調用此函數,并將類名存入參數。
```
function __autoload($classname){
?$filename = strtolower($classname).".class.php";
?if(file_exists("./action/".$filename)){
? require("./action/".$filename);
?}elseif(file_exists("./model/".$filename)){
? require("./model/".$filename);
?}else{
? die("找不到{$classname}類!");
?}
}
```
*****
php的類型約束:目前只支持array和對象(類、抽象類、接口);
*****
## 抽象類:abstract
**當類中有一個方法,他沒有方法體,直接分號結束。**
`public abstract function fun();`
**抽象方法。必須使用abstract定義。包含這種方法的類必須是抽象類。**
abstract class A
?抽象類的特點:
??????? 不能實例化,也就new成對象
?????? 若想使用抽象類,就必須定義一個類去繼承這個抽象類,并定義覆蓋父類的抽象方法(實現抽象方法)。
*****
**含有抽象方法的類肯定是抽象類,但是不是所有的抽象類都必須包含抽象方法。**
*****
```
abstract class A{
?public function fun1(){
? echo "class A method fun1...";
?}
?public abstract function fun2($a);
}
class B extends A{
?public function fun2($c){
? echo "class B method fun2...";
?}
}
class Test{
?public function demo(A $a){
? $a->fun2(10);
?}
}
$b = new B();
$b->fun1();
$b->fun2(10);
$t = new Test();
$t->demo(new B());
```
## 接口:interface
**接口:interface,假如一個抽象類中所有的方法都是抽象的,那么可以使用另外一種方式定義:接口。**
**接口中只能有常量與抽象方法。**
```
?interface 接口名{
?????????????????? [常量定義]
?????????????????? [抽象方法定義] //注意不要有abstract關鍵字
???????? ?}
?? 實現方式:class 類名? implements 接口名,接口名2{
?????????????????? 實現體。。
?? }
```
*****
//接口的定義
```
//定義一個接口A,內有兩個方法(抽象方法)
interface A{
?const PI=3.14; //在接口中可以定義常量和抽象方法
?public function fun1();
?public function fun2($a);
}
//定義一個類B去實現一個接口A
abstract class B implements A{
?public function fun1(){
? echo "class B method fun1...";
?}
}
class C extends B{
?public function fun2($c){
? echo "class C method fun2...";
?}
}
$c = new C();
$c->fun1();
$c->fun2(10);
```
## 多態:
**對于同一個方法,傳入不同的對象,實現不同的效果。**
**同一個操作作用于不同的類的實例,將產生不同的執行結果。**
思路:
? ? 定義接口/抽象類
? ? ? ? ? ? 存放抽象方法
? ? 定義類
? ? ? ? 定義方法 類型約束必須為上面定義的對象。
? ? ? ? 實現對象的抽象方法。
? ? 類1繼承接口/抽象類
? ? ? ? 重寫抽象方法。
? ? 類2繼承接口/抽象類
? ? ? ? 重寫抽象方法。
*****
實現:
//模擬多態的使用(接口版)
```
//主板的驅動程序
class mainboard{
?public function running(PCI $pci){
? $pci->start();
?}
}
//========主板廠商========
//主板上的pci插槽規范接口
interface PCI{
?public function start(); //啟動
}
//======聲卡廠家=====================
class soundcard implements PCI{
?public function start(){//啟動
? echo "聲卡啟動...";
?}
}
//======網卡廠家=====================
class networkcard implements PCI{
?public function start(){//啟動
? echo "網卡啟動...";
?}
}
//系統程序
$md = new mainBoard(); //主板程序
$sd = new soundcard(); //聲卡
$nc = new networkcard();//網卡
$md->running($sd); //聲卡接入主板程序使用
$md->running($nc); //網卡接入主板程序使用
```
\======================================
```
? ? interface employee{
? ? ? ? public function working();
? ? }
? ? class teacher impements employee{
? ? ? ? public function working(){
? ? ? ? ? ? echo '1';
? ? ? ? }
? ? }
? ? class coder implements employee{
? ? ? ? public function working(){
? ? ? ? ? ? echo '2';
? ? ? ? }
? ? }
? ? function doprint(employee $obj){
? ? ? ? $obj->working();
? ? }
? ? $a=new teacher;
? ? $b=new coder;
? ? doprint($a);
? ? doprint($b);
```
## 異常處理
```
//異常處理的使用
//除法函數
function demo($a,$b){
?if($b==0){
? //當除數為0時,自定義的拋出一個異常錯誤對象。
? throw new Exception("除數不可以為零!",110);
?}
?return $a/$b;
}
echo "start.....";
//異常處理
try{ //捕獲異常
?//調用
?echo "1aaaaaaaaa";
?echo "2aaaaaaaaa";
?echo demo(100,0);
?echo "3aaaaaaaaa";
?echo "4aaaaaaaaa";
}catch(Exception $e){ //異常處理
?echo "計算錯誤,原因:".$e->getMessage();
?echo $e->getCode().":".$e->getFile().":".$e->getLine();
}
echo "...end..";
```
- 消息隊列
- 為什么要用消息隊列
- 各種消息隊列產品的對比
- 消息隊列的優缺點
- 如何保證消息隊列的高可用
- 如何保證消息不丟失
- 如何保證消息不會重復消費?如何保證消息的冪等性?
- 如何保證消息消費的順序性?
- 基于MQ的分布式事務實現
- Beanstalk
- PHP
- 函數
- 基礎
- 基礎函數題
- OOP思想及原則
- MVC生命周期
- PHP7.X新特性
- PHP8新特性
- PHP垃圾回收機制
- php-fpm相關
- 高級
- 設計模式
- 排序算法
- 正則
- OOP代碼基礎
- PHP運行原理
- zavl
- 網絡協議new
- 一面
- TCP和UDP
- 常見狀態碼和代表的意義以及解決方式
- 網絡分層和各層有啥協議
- TCP
- http
- 二面
- TCP2
- DNS
- Mysql
- 鎖
- 索引
- 事務
- 高可用?高并發?集群?
- 其他
- 主從復制
- 主從復制數據延遲
- SQL的語?分類
- mysqlQuestions
- Redis
- redis-question
- redis為什么那么快
- redis的優缺點
- redis的數據類型和使用場景
- redis的數據持久化
- 過期策略和淘汰機制
- 緩存穿透、緩存擊穿、緩存雪崩
- redis的事務
- redis的主從復制
- redis集群架構的理解
- redis的事件模型
- redis的數據類型、編碼、數據結構
- Redis連接時的connect與pconnect的區別是什么?
- redis的分布式鎖
- 緩存一致性問題
- redis變慢的原因
- 集群情況下,節點較少時數據分布不均勻怎么辦?
- redis 和 memcached 的區別?
- 基本算法
- MysqlNew
- 索引new
- 事務new
- 鎖new
- 日志new
- 主從復制new
- 樹結構
- mysql其他問題
- 刪除
- 主從配置
- 五種IO模型
- Kafka
- Nginx
- trait
- genergtor 生成器
- 如何實現手機掃碼登錄功能
- laravel框架的生命周期