php 物件導向筆記

來源:互聯網
上載者:User
===================================================
PHP的物件導向:

對象是客觀存在的一個實體。
類是對對象抽象的一個描述。

概念:對象(實體)、類、 類與對象的關係。

oop物件導向編程的特點:封裝、繼承、多態

類和對象的關係:
類的執行個體化結果就是一個對象(使用new關鍵字)
對對象的抽象描述就是一個類

===================================================
一、如何定義一個類,和使用

1.1 文法格式:
[修飾符] class 類名 [extends 父類] [implements 介面1[,介面2...]]{
【成員屬性】定義變數
【成員方法】定義函數
}

1.2 成員屬性格式:
修飾符 $變數名[=預設值]; 如:public $name="zhangsan";
注意:成員屬性不可以是帶運算子的運算式、變數、方法或函數的調用。 如:
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
正確定義方式:
public $var6 = 100; //普通數值(4個標量:整數、浮點數、布爾、字串)
public $var6 = myConstant; //常量
public $var7 = self::classConstant; //靜態屬性
public $var8 = array(true, false); //數組

常用的屬性修飾符:public、protected、private、static、var

1.3 成員方法格式:
[修飾符] function 方法名(參數..){
[方法體]
[return 傳回值]
}

常用的方法修飾符:public、protected、private、static、abstract、final

1.4 對象:類的執行個體化就會產生一個對象。
如: $p = new Person();

1.5 $this 關鍵字: 表示自己,表示當前使用對象,*哪個對象調用代表哪個
1.我們在類中調用自己的成員屬性或方法都是使用 $this->調用。
2.注意:靜態方法不可以使用$this關鍵字

===================================================
二、構造方法和析構方法

2.1. 構造方法:
1.當我們通過new關鍵字來建立一個對象時,第一個自動執行的方法稱為構造方法。

2.方法名__construct(); 主要用於初始化對象。
(在php4.0時可使用與類名重名的方法作為構造方法)

2.2. 析構方法:當這個對象被銷毀時最後自動調用的方法,稱為析構方法。
1.__destruct(); 目的是釋放資源(如關閉串連、檔案,釋放資源)

2.對象被銷毀時最後自動調用

===================================================
三、封裝(存取控制)

3.1 封裝:就是將"屬性" private或protected 私人,並提供公有的setter放置與getter取值方法

public(公有) protected(受保護) private(私人)
===========================================================
在本類中 Y Y Y
在家族中 Y Y N
在類外邊 Y N N

public 類外需要調用此類內的方法或屬性時使用
protected 類外不需要調用,而家族內需要使用
private 用於安全資訊,只用於當前類

===================================================
四、 重載

4.1 屬性重載中的四個魔術方法:__set() __get() __isset() __unset()

__get():當我們直接輸出一個對象中的非公有屬性時會自動調用的方法,
並將屬性名稱以第一個參數傳進去。
__get($name){...} //外部:$m->priAge;

__set():當我們直接設定一個對象中的非公有屬性時會自動調用的方法,
並將屬性名稱以第一個參數,值作為第二參數傳進去。
__set($name,$value){...} //外部:$m->priAge = 100;

__isset():驗證一個對象屬性isset($this->name) 或 empty($this->name)時, $this->name是一個非公有屬性時,自動調用此方法。
public function __isset($param){
return isset($this->$param);
}

__unset()當銷毀一個對象屬性unset($this->name), $this->name是一個非公有屬性時,自動調用此方法。
public function __unset($param){
unset($this->$param);
}

4.2 方法的重載:
mixed __call ( string $name , array $arguments )
mixed __callStatic ( string $name , array $arguments ) php5.3.0支援

1.當調用一個不可存取方法(如未定義,或者不可見)時,__call() 會被調用。
2.當在靜態方法中調用一個不可存取方法(如未定義,或者不可見)時,__callStatic() 會被調用。

第一個參數表示方法名,第二參數表示調用時的參數列表(數群組類型)

class A {
//調用不存在的方法
public function __call($methodName,$args) {
echo $methodName;
print_r($args);
}

//調用不存在的靜態方法
static public function __callStatic($methodName,$args) {
echo '
'.$methodName;
print_r($args);
}
}
$a = new A;
$a->say('a','b');
A::test('c','d');

===================================================
五、 繼承

5.1 繼承:extends
*繼承的目的:為了減少重複的代碼。

假如B類繼承A類,那麼就繼承了A中所有非私人屬性和方法.其中A叫父類(基類)B叫子類(衍生類別)。
class B extends A{
....
}

1.*parent:若子類出現覆蓋父類的方法,那麼想調用被覆蓋掉的父類方法,並可以跟子類的方法融合為一起

格式:parent::父類方法 | 父類名稱::父類方法

class A{
public function __construct(){
//....
}
}
class B extends A{
public function __construct(){
parent::__construct();//注意要調用一下父類的構造方法
//....
}
}

2.繼承的特性
1、PHP支援單繼承,一類只能繼承一個父類
2、PHP支援多層繼承,可以有子孫類
3、子類會繼承父類所有屬性和方法,但是私人的屬性和方法不能調用

3.屬性的繼承
1、私人的屬性不會被覆蓋,其他會被覆蓋。
2、屬性的修飾只能更加鬆散,不能更加嚴謹。 鬆散性:public > protected > private
3、如果子類中有與父類同名的屬性,父類有public $name 子類只能使用public修飾
3、如果子類中有與父類同名的屬性,父類有protected $name 子類能使用protected,public修飾

4.方法的繼承
1、所有方法可以被繼承,但是私人的方法不能被使用
2、如果子類有與父類同名的方法,那麼除了私人的方法,其他都被覆蓋掉。
3、如果子類有與父類同名的方法,方法的修飾只能更加鬆散,不能更嚴謹。

===================================================
六、 final、static和const
*記憶體邏輯上:常量區(常量、靜態屬性)、代碼區(類、函數)、棧記憶體(普通的小的變數)、堆記憶體(大的變數)

6.1 final關鍵字:主要用於修飾類與成員方法
目的:一是為了安全,二是沒有必要

1.使用final關鍵字修飾類,表示這個類不能被繼承,防止有子類的覆蓋

2.使用final關鍵字修飾的方法,不可以在子類中被覆蓋(重寫)。

3.使用final關鍵字不能修飾屬性

final class B {
final public function A {
..
}
}
---------------------------------------------------------------
6.2 static關鍵字:表示靜態意思,用於修飾類的屬性和方法

static關鍵字修飾 屬性/方法 稱為 靜態屬性/靜態方法,
注意:靜態方法在執行個體化後的對象不可以訪問 //$對象名->靜態方法名

1.可以不用new(執行個體化)就可以直接使用方法或屬性
*外部調用:類名::方法名 | 類名::屬性名稱
*類中調用:self::靜態屬性名 | self::靜態方法名

*2.靜態屬性是共用的。也就是調用多個對象也是指向同一個地址

3.在靜態方法中不可以使用非靜態內容。就是不讓使用$this

4.在一個類的方法中若沒有出現$this的調用,預設此方法為靜態方法。

5.static不能修飾類

---------------------------------------------------------------
6.21 設計模式。目的:節省資源

1、單例設計模式 2、工廠設計模式 3、 抽象工廠設計模式

class Single
{
//定義一個靜態屬性,用來存放對象
static private $obj = null;

//私人化構造方法。不能在類的外部執行個體化對象
private function __construct() {}

//執行個體化對象
static public function test() {
//如果沒有對象,我們就允許它new一個對象
if(!self::$obj) {
self::$obj = new Single();//建立對象
}

//有了對象,就直接返回之前的對象
return self::$obj;
}

//單例不允許複製
public function __clone() {
trigger_error('錯誤', E_USER_ERROR);
}
}

$s1 = Single::test(); var_dump($s1);
$s2 = Single::test(); var_dump($s2); //調用同一個對象

$s3 = clone $s2; //報錯

---------------------------------------------------------------
6.3. const關鍵字: 在類中修飾成員屬性,將其定義成常量(不可修改的),

1.一般要求常量名都是大寫的,沒有“$”符 沒有其他修飾符(public)

2.定義格式:const 成員常量名="值";

3.使用:
*外部調用:類名::成員常量名;
*類中調用:self::成員常量名;

---------------------------------------------------------------
6.4. 檢測當前對象是屬於誰的類(家族類也是)

1.instanceof 用於確定一個 PHP 變數是否屬於某一類 class 的執行個體:

class A {}
class B extends A {}
$b = new B;
if($b instanceof A) {echo 'y';}

2.is_a — 如果對象屬於該類或該類是此對象的父類則返回 TRUE

===================================================
七、 類型約束

1. 類型約束可以使用的類型是:數組,對象,回呼函數。
若指定的一個類名,那麼可傳入本類及子類的對象進去。
可以使用的約束類型:(複合類型)數組array,類名、抽象類別名、介面名

class MyClass
{
//第一個參數必須為類OtherClass的一個對象
public function test(OtherClass $otherclass) {
**可以傳入別的類,調用別的類的方法和屬性
echo $otherclass->var;

//同這裡
if( $otherclass instanceof Hanzi){
$otherclass->qinqin();
}
}

//第一個參數必須為數組
public function test_array(array $input_array) {
print_r($input_array);
}
}

===================================================
八、其他魔術方法:

1. 對象複製clone 複製一個對象,因為對象屬於參考型別,普通的“=”號屬於引用賦值,
所有需要clone來複製一份。
魔術方法:__clone() 當執行clone複製時會自動調用的方法。

class A {
public function __clone() {
//自動執行
}
}

$a = new A;
$b = clone $a; //複製,是兩個對象

-----------------------------------------------------------------
2. __toString()方法:魔術方法,當我們直接要輸出一個對象時,如echo $a,print $a,
那麼會自動調用的方法。
注意:__toString()方法必須返回一個字串類型的值。

class A {
public function __toString() {
return '這是一個對象,不允許ehco,print...';
}
}
$a = new A;
echo $a; //報錯

-----------------------------------------------------------------
3. *自動載入"類函數"__autoload(類名):
當new 執行個體化一個對象時,這個類若不存在,則自動調用此函數,並將類名存入參數
我可以使用這個實作類別的自動載入。

function __autoload($className) {
include './autoload/'.$className.'.class.php';
}

$a = new A;
$a->say(); //say

//在 autoload/A.class.php下
class A{
public function say() {
echo 'say';
}
}

-----------------------------------------------------------------
4. __invoke把對象當成函數使用的時候自動調用

class A {
public function __invoke() {
echo 'aa';
}
}

$a = new A;
$a(); //aa

===================================================
九、 對象序列化(序列化)(webservice XML)(在對象持久化儲存、和傳輸中使用)

serialize() -- 序列化
unserialize() -- 還原序列化

1.php裡面的值都可以使用函數serialize()來返回一個包含位元組流的字串來表示。
2.unserialize()函數能夠重新把字串變回php原來的值。
3.序列化一個對象將會儲存對象的所有變數,但是不會儲存對象的方法,只會儲存類的名字。

1.__sleep(): 是執行序列化時自動調用的方法,目的是實現資源類型的屬性的關閉操作。
@@sleep方法需要返回一個數組,其中數組中的值是序列化時要保留的屬性名稱
2.__wakeup():是在執行反序列化時自動調用的方法,目的是實現資源屬性的開啟(sleep方法關閉的資源)

//執行個體:
class A {
public $name1 = 'xiaohei';
public $name2 = 'xiaobai';

public function demo() {
return 'aa';
}

//序列化自動調用的方法
public function __sleep() {
return array('name2'); //只想儲存name2,就返回name2
}

//還原序列化自動調用的方法
public function __wakeup() {
echo '###';
}
}

$a = new A;

//序列化
$data = serialize($a);

//存入檔案
file_put_contents('./1.txt', $data);

//獲得資料
$str = file_get_contents('./1.txt');

echo $str; //O:1:"A":1:{s:4:"name";s:7:"xiaohei";}

//還原序列化
$tmp = unserialize($str);

print_r($tmp); //A Object ( [name] => xiaohei )

-------------------------------------------------------------------------------------
JSON格式的字串進行編碼/解碼

json_encode:對變數進行 JSON 編碼
json_decode:對 JSON 格式的字串進行編碼

$arr = array('id'=>1, 'name'=>'jack');

$str1 = json_encode($arr);
echo $str1; //{"id":1,"name":"jack"}

$a = json_decode($str1, true); //加true返回array,否則返回object
echo $a; //Array ( [id] => 1 [name] => jack )

===================================================
十、 抽象類別:

目的:抽象類別對於子類(實作類別),有一個約束的作用,

特點:
//1.定義抽象類別
abstract class A {
//2.定義抽象方法
abstract public function test1();
abstract public function test2();

//3.可以有普通方法和屬性,不需要子級實現
public function demo() {}
public $name = 'aa';

//4.不能定義抽象屬性 Fatal error
abstract public $age = 18;
}

class B extends A {
//5.@@繼承了抽象類別的"普通類"必須實現抽象類別的"所有抽象方法"
public function test1() {}
public function test2() {}

//6.包含了抽象方法的類必須是抽象類別,Fatal error
abstract function test3() {}
}

abstract class C extends A {
//7.不能覆蓋抽象方法,Fatal error
abstract public function test1() {}

//8.可以繼承抽象類別的同時添加抽象方法
abstract public function test3();
}

//8.不能執行個體化,Fatal error
$c = new C;

===================================================
十一、 介面:

目的:同抽象類別相同,是更具體的抽象類別
假如一個抽象類別中所有的方法都是抽象的,那麼我們可以使用另外一種方式定義:介面
介面使用關鍵字interface來定義,介面中只能有常量與抽象方法。

//1.定義介面
interface A {
//2.介面不能有普通屬性,Fatal error
public $name = 'aa';

//3.介面不能有普通方法,Fatal error
public function test() {}

//3.但可以定義常量
const HOST = 'aa';

//4.定義介面方法,不需要abstract
public function test1();

}

interface B {
//5.介面之間是繼承關係,重複定義Fatal error
const HOST = 'bb';

public function test2();
}

class C {}

//6.可以同時繼承"單"類、實現"多"介面(先繼承,後實現)
class D extends C implements A,B {
//7.@@繼承了抽象類別的"普通類"必須實現抽象類別的"所有抽象方法"
public function test1() {}
public function test2() {}
}

抽象類別和介面總結:
1.目的:制定規範,為了限制其子類
2.選擇:如果規範中需要有"普通方法"就選擇抽象類別
3.區別:
1.定義關鍵字不同。抽象類別:abstract 介面:interface
2.繼承/實現關鍵字不同。抽象類別:extends 介面:implements
3.抽象類別可以有普通方法,介面不能有普通方法
4.抽象類別只能被單繼承,介面可以多實現
5.介面不能有成員屬性,只有常量與抽象方法

===================================================
十二、多態

定義:對於“同一個方法”,傳入“不同對象”,實現了不同的效果

class Meizi {
public function meet($obj) {
//限制了對象必須有qinqin()這個方法
if( $obj instanceof Hanzi){
//同一個方法
$obj->qinqin();
}else{
echo '你不會親親這個功能!';
}
}
}

//抽象類別
abstract class Hanzi
{
abstract public function qinqin();
}

//大屌絲類
class DDS extends Hanzi {
public function qinqin() {
echo '被妹子打了一巴掌,這就是DDS的命運';
}
}

//高富帥類
class GFS extends Hanzi {
public function qinqin() {
echo '不僅僅親親,還啪啪啪,這是高富帥的命運';
}
}

//萌妹子類
class MengMeizi {}

$m = new Meizi;
$dds = new DDS;
$gfs = new GFS;
$mmz = new MengMeizi;

//傳入對象
echo $m->meet($dds); //實現了DDS的效果
echo $m->meet($gfs); //實現了GFS的效果

//沒有限制
echo $m->meet($mmz); //你不會親親!

@@多態的兩個執行個體:
./1.通過介面實現多態的應用.php
./2.通過普通類實現多態的應用.php

===================================================
十三、異常處理:
在php5中有一種新的錯誤處理機制--異常處理:(採用物件導向方式的)
涉及的類:Exception異常類
Exception類結構:
class Exception
{
protected $message = 'Unknown exception'; // 異常資訊
protected $code = 0; // 使用者自訂異常代碼
protected $file; // 發生異常的檔案名稱
protected $line; // 發生異常的程式碼號

function __construct($message = null, $code = 0);

final function getMessage(); // 返回異常資訊
final function getCode(); // 返回異常代碼
final function getFile(); // 返回傳生異常的檔案名稱
final function getLine(); // 返回傳生異常的程式碼號
final function getTrace(); // backtrace() 數組
final function getTraceAsString(); // 已格成化成字串的 getTrace() 資訊

/* 可重載的方法 */
function __toString(); // 可輸出的字串
}

使用:
try{
throw new Exception("年齡不可以為負數"); //異常拋出
}catch(Exception $e){
//異常處理
echo $e->getmessage();
}

執行個體:
function addUser($username) {
if($username="xiaobai") {
//添加成功
}else {
//添加失敗
throw new Exception('添加失敗');
}
}

function updateUser($username) {
if($username = "xiaohei") {
//修改成功
}else {
//修改失敗
throw new Exception('修改失敗');
}
}

try {
addUser('xiaobaia');

updateUser('xiaohei');
}catch(Exception $e) {

echo '失敗資訊是:'.$e->getMessage();
}

@@當捕獲到一個異常後,try()塊裡面的後續代碼不繼續執行

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.