PHP面向物件技術(全面講解)
PHP面向物件技術(全面講解)(高洛峰)
本部分一共包括以下一些技術點:
1.面象物件的概念
2.什麼是類, 什麼是物件, 類和物件這間的關係
3.什麼是面向物件程式設計呢?
4.如何抽象出一個類?
5.如何例項化物件
6.如何去使用物件中的成員
7.特殊的引用“$this“的使用
8.構造方法與析構方法
9.封裝性
10.__set() __get() __isset() __unset()四個方法的應用
11.類的繼函
13.過載新的方法
14.訪問型別
15.靜態成員以及類中常量的使用
16.final關鍵字的應用
17.__toString()方法
18.
19.__call處理呼叫錯誤
20.自動載入類
21.把物件序列化
22.抽象方法和抽象類
23.php5介面技術
12.多型的應用
1.面象物件的概念
面向物件程式設計(Object Oriented Programming, OOP, 面向物件程式設計)是一種計算機程式設計架構,OOP的一條基本原則是計算機程式是由單個能夠起到子程式作用的單元或物件組合而成,OOP達到了軟體工程的三個目標:重用性、靈活性和擴充套件性。為了實現整體運算,每個物件都能夠接收資訊、處理資料和向其它物件傳送資訊。面向物件一直是軟體開發領域內比較熱門的話題,首先,面向物件符合人類看待事物的一般規律。其次,採用面向物件方法可以使系統各部分各司其職、各盡所能。為程式設計人員敞開了一扇大門,使其程式設計的程式碼更簡潔、更易於維護,並且具有更強的可重用性。有人說PHP
2.什麼是類, 什麼是物件, 類和物件這間的關係
類的概念:類是具有相同屬性和服務的一組物件的集合。它為屬於該類的所有物件提供了統一的抽象描述,其內部包括屬性和服務兩個主要部分。在面向物件的程式語言中,類是一個獨立的程式單位,它應該有一個類名幷包括屬性說明和服務說明兩個主要部分。
物件的概念:物件是系統中用來描述客觀事物的一個實體,它是構成系統的一個基本單位。一個物件由一組屬性和對這組屬性進行操作的一組服務組成。從更抽象的角度來說,物件是問題域或實現域中某些事物的一個抽象,它反映該事物在系統中需要儲存的資訊和發揮的作用;它是一組屬性和有權對這些屬性進行操作的一組服務的封裝體。客觀世界是由物件和物件之間的聯絡組成的。
類與物件的關係就如模具和鑄件的關係,類的例項化結果就是物件,而對一類物件的抽象就是類.類描述了一組有相同特性(屬性)和相同行為(方法)的物件。
上面大概就是它們的定義吧, 也許你是剛接觸面象物件的朋友, 不要被概念的東西搞暈了, 給你舉個列子吧,如果你去中關村想買幾臺組裝的PC機,到了那裡你第一步要幹什麼, 是不是裝機的工程師和你坐在一起,按你提供的資訊和你一起完成一個裝機的配置單呀, 這個配置單就可以想像成是類,它就是一張紙,但是它上面記錄了你要買的PC機的資訊,如果用這個配置單買10臺機器,那麼這10臺機子,都是按這個配置單組成的,所以說這10臺機子是一個型別的,也可以說是一類的。那麼什麼是物件呢,類的例項化結果就是物件, 用這個配置單配置出來(例項化出來)的機子就是物件, 是我們可以操作的實體, 10臺機子, 10個物件。 每臺機子都是獨立的,只能說明他們是同一類的,對其中一個機做任何動作都不會影響其它9臺機器,但是我對類修改, 也就是在這個配置單上加一個或少一個配件, 那麼裝出來的9個機子都改變了, 這是類和物件的關係(類的例項化結果就是物件).
3.什麼是面向物件程式設計呢?
就不說他的概念,如果你想建立一個電腦教室,首先要有一個房間, 房間裡面要有N臺電腦,有N個桌子, N個椅子, 白板, 投影機等等,這些是什麼,剛才咱們說了, 這就是物件,能看到的一個個的實體,可以說這個電腦教室的單位就是這一個個的實體物件, 它們共同組成了這個電腦教室,那麼我們是做程式,這和麵向物件有什麼關係呢?開發一個系統程式和建一個電腦教室類似,你把每個獨立的功能模組抽象成類形成物件,由多個物件組成這個系統,這些物件之間都能夠接收資訊、處理資料和向其它物件傳送資訊等等相互作用。就構成了面向物件的程式。
4.如何抽象出一個類?
上面已經介紹過了, 面向物件程式的單位就是物件,但物件又是通過類的例項化出來的,所以我們首先要做的就是如何來宣告類, 做出來一個類很容易,只要掌握基本的程式語法定義規則就可以做的出來,那麼難點在那裡呢? 一個專案要用到多少個類,用多少個物件, 在那要定義類,定義一個什麼樣的類,這個類例項化出多少個物件, 類裡面有多少個屬性, 有多少個方法等等,這就需要讀者通過在實際的開發中就實際問題分析設計和總結了。
類的定義:
class 類名{
}
使用一個關鍵字class和後面加上一個你想要的類名以及加上一對大括號, 這樣一個類的結構就定義出來了,只要在裡面寫程式碼就可以了, 但是裡面寫什麼? 能寫什麼?怎樣寫才是一個完整的類呢?上面講過來,使用類是為了讓它例項出物件來給我們用, 這就要知道你想要的是什麼樣的物件了,像上面我們講的一個裝機配置單上寫什麼,你裝出來的機子就有什麼。比如說,一個人就是一個物件,你怎麼把一個你看好的人推薦給你們領導呢?當然是越詳細越好了:
首先, 你會介紹這個人姓名、性別、年齡、身高、體重、電話、家庭住址等等。
然後,你要介紹這個人能做什麼, 可以開車, 會說英語, 可以使用電腦等等。
只要你介紹多一點, 別人對這個人就多一點了解, 這就是我們對一個人的描述, 現在我們總結一下,所有的物件我們用類去描述都是類似的, 從上面人的描述可以看到, 做出一個類來, 從定義的角度分兩部分, 第一是從靜態上描述, 第二是從動態上描述, 靜態上的描述就是我們所說的屬性, 像上面我們看到的,人的姓名、性別、年齡、身高、體重、電話、家庭住址等等。 動態上也就是人的這個物件的功能,比如這個人可以開車, 會說英語, 可以使用電腦等等,抽象成程式時,我們把動態的寫成函式或者說是方法,函式和方法是一樣的。所以,所有類都是從屬性和方法這兩方面去寫, 屬性又叫做這個類的成員屬性,方法叫做這個類的成員方法。
class 人{
成員屬性:姓名、性別、年齡、身高、體重、電話、家庭住址
成員方法:可以開車, 會說英語, 可以使用電腦
}
屬性:
通過在類定義中使用關鍵字" var"來宣告變數,即建立了類的屬性,雖然在宣告成員屬性的時候可以給定初值, 但是在宣告類的時候給成員屬性初使值是沒有必要的,比如說要是把人的姓名賦上“張三”,那麼用這個類例項出幾十個人,這幾十個人都叫張三了,所以沒有必要, 我們在例項出物件後給成員屬性初使值就可以了。
如: var$somevar;
方法(成員函式):
通過在類定義中宣告函式,即建立了類的方法。
如: functionsomefun(引數列表)
{... ...}
<?php
class Person
{
//下面是人的成員屬性
var $name;//人的名子
var $sex;//人的性別
var $age;//人的年齡
//下面是人的成員方法
function say() //這個人可以說話的方法
{
echo "這個人在說話";
}
function run() //這個人可以走路的方法
{
echo "這個人在走路";
}
}
?>
上面就是一個類的宣告, 從屬性和方法上宣告出來的一個類, 但是成員屬性最好在宣告的時候不要給初使的值, 因為我們做的人這個類是一個描述資訊, 將來用它例項化物件, 比如例項化出來10個人物件, 那麼這10個人, 每一個人的名子, 性別, 年齡都是不一樣的, 所以最好不要在這個地方給成員屬性賦初值, 而是對每個物件分別賦值的。
用同樣的辦法可以做出你想要的類了, 只要你能用屬性和方法能描述出來的實體都可以定義成類, 去例項化物件。
為了加強你對類的理解, 我們再做一個類, 做一個形狀的類, 形狀的範圍廣了點, 我們就做個矩形吧, 先分析一下, 想一想從兩方面分析,矩形的屬性都有什麼? 矩形的功能都有什麼?
class 矩形
{
//矩形的屬性
矩形的長;
矩形的寬;
//矩形的方法
矩形的周長;
矩形的面積;
}
<?php
class Rect
{
var $kuan;
var $gao;
function zhouChang()
{
計算矩形的周長;
}
function mianJi()
{
計算矩形的面積;
}
}
?>
如果用這個類來創建出多個矩形物件,每個矩形物件都有自己的長和寬, 都可以求出自己的周長和麵積了。
類的宣告我們就到這裡吧!!
5.如何例項化物件
我們上面說過面向物件程式的單位就是物件,但物件又是通過類的例項化出來的,既然我們類會聲明瞭,下一步就是例項化物件了。
當定義好類後,我們使用new關鍵字來生成一個物件。
$物件名稱 = new 類名稱();
<?php
class Person
{
//下面是人的成員屬性
var $name;//人的名子
var $sex;//人的性別
var $age;//人的年齡
//下面是人的成員方法
function say()//這個人可以說話的方法
{
echo "這個人在說話";
}
function run()//這個人可以走路的方法
{
echo "這個人在走路";
}
}
$p1=new Person();
$p2=new Person();
$p3=new Person();
?>
$p1=new Person();
這條程式碼就是通過類產生例項物件的過程,$p1就是我們例項出來的物件名稱, 同理,$p2, $p3也是我們例項出來的物件名稱,一個類可以例項出多個物件,每個物件都是獨立的,上面的程式碼相當於例項出來3個人來, 每個人之間是沒有聯絡的, 只能說明他們都是人類, 每個人都有自己的姓名, 性別和年齡的屬性,每個人都有說話和走路的方法,只要是類裡面體現出來的成員屬性和成員方法,例項化出來的物件裡面就包含了這些屬性和方法。
對像在PHP裡面和整型、浮點型一樣,也是一種資料類,都是儲存不同型別資料用的,在執行的時候都要載入到記憶體中去用, 那麼物件在記憶體裡面是怎麼體現的呢?記憶體從羅輯上說大體上是分為4段, 棧空間段, 堆空間段,程式碼段, 初使化靜態段,程式裡面不同的宣告放在不同的記憶體段裡面,棧空間段是儲存佔用相同空間長度並且佔用空間小的資料型別的地方,比如說整型1, 10, 100, 1000, 10000, 100000等等,在記憶體裡面佔用空間是等長的,都是64位4個位元組。 那麼資料長度不定長,而且佔有空間很大的資料型別的資料放在那記憶體的那個段裡面呢?這樣的資料是放在堆記憶體裡面的。棧記憶體是可以直接存取的,而堆記憶體是不可以直接存取的記憶體。對於我們的物件來數就是一種大的資料型別而且是佔用空間不定長的型別,所以說物件是放在堆裡面的,但物件名稱是放在棧裡面的,這樣通過物件名稱就可以使用物件了。
$p1=new Person();
對於這個條程式碼, $p1是物件名稱在棧記憶體裡面,new Person()是真正的物件是在堆記憶體裡面的,具體的請看下圖:
從上圖可以看出$p1=new Person();等號右邊是真正的物件例項, 在堆記憶體裡面的實體,上圖一共有3次new Person(),所以會在堆裡面開闢3個空間,產生3個例項物件,每個物件之間都是相互獨立的,使用自己的空間,在PHP裡面,只要有一個new這個關鍵字出現就會例項化出來一個物件,在堆裡面開闢一塊自己的空間.
每個在堆裡面的例項物件是儲存屬性的,比如說,現在堆裡面的例項物件裡面都存有姓名、性別和年齡。每個屬性又都有一個地址。
$p1=new Person();等號的右邊$p1是一個引用變數,通過賦值運算子“=”把物件的首地址賦給“$p1“這個引用變數, 所以$p1是儲存物件首地址的變數,$p1放在棧記憶體裡邊,$p1相當於一個指標指向堆裡面的物件, 所以我們可以通過$p1這個引用變數來操作物件, 通常我們也稱物件引用為物件。
6.如何去使用物件中的成員
上面看到PHP物件中的成員有兩種一種是成員屬性, 一種是成員方法。物件我們以經可以聲明瞭,$p1=new Person(); 怎麼去使用物件的成員呢?要想訪問物件中的成員就要使用一個特殊的操作符”->”來完成物件成員的訪問:
物件->屬性$p1->name;$p2->age; $p3->sex;
物件->方法$p1->say();$p2->run();
如下面例項:
<?php
class Person
{
//下面是人的成員屬性
var $name;//人的名子
var $sex;//人的性別
var $age;//人的年齡
//下面是人的成員方法
function say()//這個人可以說話的方法
{
echo "這個人在說話";
}
function run()//這個人可以走路的方法
{
echo "這個人在走路";
}
}
$p1=new Person();//建立例項物件$p1
$p2=new Person();//建立例項物件$p2
$p3=new Person();//建立例項物件$p3
//下面三行是給$p1物件屬性賦值
$p1->name=”張三”;
$p1->sex=”男”;
$p1->age=20;
//下面三行是訪問$p1物件的屬性
echo “p1物件的名子是:”.$p1->name.”<br>”;
echo “p1物件的性別是:”.$p1->sex.”<br>”;
echo “p1物件的年齡是:”.$p1->age.”<br>”;
//下面兩行訪問$p1物件中的方法
$p1->say();
$p1->run();
//下面三行是給$p2物件屬性賦值
$p2->name=”李四”;
$p2->sex=”女”;
$p2->age=30;
//下面三行是訪問$p2物件的屬性
echo “p2物件的名子是:”.$p2->name.”<br>”;
echo “p2物件的性別是:”.$p2->sex.”<br>”;
echo “p2物件的年齡是:”.$p2->age.”<br>”;
//下面兩行訪問$p2物件中的方法
$p2->say();
$p2->run();
//下面三行是給$p3物件屬性賦值
$p3->name=”王五”;
$p3->sex=”男”;
$p3->age=40;
//下面三行是訪問$p3物件的屬性
echo “p3物件的名子是:”.$p3->name.”<br>”;
echo “p3物件的性別是:”.$p3->sex.”<br>”;
echo “p3物件的年齡是:”.$p3->age.”<br>”;
//下面兩行訪問$p3物件中的方法
$p3->say();
$p3->run();
?>
從上例中可以看出只是物件裡面的成員就要使用物件->屬性、物件->方法形式訪問,再沒有第二種方法來訪問物件中的成員了。
7.特殊的引用“$this“的使用
現在我們知道了如何訪問物件中的成員,是通過”物件->成員”的方式訪問的,這是在物件的外部去訪問物件中成員的形式,那麼如果我想在物件的內部,讓物件裡的方法訪問本物件的屬性,或是物件中的方法去呼叫本物件的其它方法這時我們怎麼辦?因為物件裡面的所有的成員都要用物件來呼叫,包括物件的內部成員之間的呼叫,所以在PHP裡面給我提供了一個本物件的引用$this,每個物件裡面都有一個物件的引用$this來代表這個物件,完成物件內部成員的呼叫, this的本意就是“這個”的意思,上面的例項裡面,我們例項化三個例項物件$P1、 $P2、 $P3,這三個物件裡面各自存在一個$this分別代表物件$p1、$p2、$p3 。
通過上圖我們可以看到,$this就是物件內部代表這個物件的引用,在物件內部和呼叫本物件的成員和物件外部呼叫物件的成員所使用的方式是一樣的。
$this->屬性$this->name;$this->age; $this->sex;
$this->方法$this->say();$this->run();
修改一下上面的例項,讓每個人都說出自己的名字,性別和年齡:
<?php
class Person
{
//下面是人的成員屬性
var $name;//人的名子
var $sex;//人的性別
var $age;//人的年齡
//下面是人的成員方法
function say()//這個人可以說話的方法
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
}
function run()//這個人可以走路的方法
{
echo "這個人在走路";
}
}
$p1=new Person();//建立例項物件$p1
$p2=new Person();//建立例項物件$p2
$p3=new Person();//建立例項物件$p3
//下面三行是給$p1物件屬性賦值
$p1->name="張三";
$p1->sex="男";
$p1->age=20;
//下面訪問$p1物件中的說話方法
$p1->say();
//下面三行是給$p2物件屬性賦值
$p2->name="李四";
$p2->sex="女";
$p2->age=30;
//下面訪問$p2物件中的說話方法
$p2->say();
//下面三行是給$p3物件屬性賦值
$p3->name="王五";
$p3->sex="男";
$p3->age=40;
//下面訪問$p3物件中的說話方法
$p3->say();
?>
輸出結果為:
我的名子叫:張三 性別:男 我的年齡是:20
我的名子叫:李四 性別:女 我的年齡是:30
我的名子叫:王五 性別:男 我的年齡是:40
分析一下這個方法:
function say()//這個人可以說話的方法
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
}
在$p1、$p2和$p3這三個物件中都有say()這個方法,$this分別代表這三個物件, 呼叫相應的屬性,打印出屬性的值,這就是在物件內部訪問物件屬性的方式, 如果相在say()這個方里呼叫run()這個方法也是可以的,在say()這個方法中使用$this->run()的方式來完成呼叫。
8.構造方法與析構方法
大多數類都有一種稱為建構函式的特殊方法。當建立一個物件時,它將自動呼叫建構函式,也就是使用new這個關鍵字來例項化物件的時候自動呼叫構造方法。
建構函式的宣告與其它操作的宣告一樣,只是其名稱必須是__construct( )。這是PHP5中的變化,以前的版本中,建構函式的名稱必須與類名相同,這種在PHP5中仍然可以用,但現在以經很少有人用了,這樣做的好處是可以使建構函式獨立於類名,當類名發生改變時不需要改相應的建構函式名稱了。為了向下相容,如果一個類中沒有名為__construct( )的方法,PHP將搜尋一個php4中的寫法,與類名相同名的構造方法。
格式:function __construct ( [引數] ) { ... ... }
在一個類中只能宣告一個構造方法,而是隻有在每次建立物件的時候都會去呼叫一次構造方法,不能主動的呼叫這個方法,所以通常用它執行一些有用的初始化任務。比如對成屬性在建立物件的時候賦初值。
<?
//建立一個人類
class Person
{
//下面是人的成員屬性
var $name;//人的名子
var $sex;//人的性別
var $age;//人的年齡
//定義一個構造方法引數為姓名$name、性別$sex和年齡$age
function __construct($name, $sex, $age)
{
//通過構造方法傳進來的$name給成員屬性$this->name賦初使值
$this->name=$name;
//通過構造方法傳進來的$sex給成員屬性$this->sex賦初使值
$this->sex=$sex;
//通過構造方法傳進來的$age給成員屬性$this->age賦初使值
$this->age=$age;
}
//這個人的說話方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
}
}
//通過構造方法建立3個物件$p1、p2、$p3,分別傳入三個不同的實參為姓名、性別和年齡
$p1=new Person(“張三”,”男”, 20);
$p2=new Person(“李四”,”女”, 30);
$p3=new Person(“王五”,”男”, 40);
//下面訪問$p1物件中的說話方法
$p1->say();
//下面訪問$p2物件中的說話方法
$p2->say();
//下面訪問$p3物件中的說話方法
$p3->say();
?>
輸出結果為:
我的名子叫:張三 性別:男 我的年齡是:20
我的名子叫:李四 性別:女 我的年齡是:30
我的名子叫:王五 性別:男 我的年齡是:40
如圖:
解構函式:
與建構函式相對的就是解構函式。解構函式是PHP5新新增的內容,在PHP4中沒有解構函式。解構函式允許在銷燬一個類之前執行的一些操作或完成一些功能,比如說關閉檔案,釋放結果集等,解構函式會在到某個物件的所有引用都被刪除或者當物件被顯式銷燬時執行,也就是物件在記憶體中被銷燬前呼叫解構函式。與建構函式的名稱類似,一個類的解構函式名稱必須是__destruct( )。解構函式不能帶有任何引數。
格式:function __destruct ( ) { ... ... }
<?
//建立一個人類
class Person
{
//下面是人的成員屬性
var $name;//人的名子
var $sex;//人的性別
var $age;//人的年齡
//定義一個構造方法引數為姓名$name、性別$sex和年齡$age
function __construct($name, $sex, $age)
{
//通過構造方法傳進來的$name給成員屬性$this->name賦初使值
$this->name=$name;
//通過構造方法傳進來的$sex給成員屬性$this->sex賦初使值
$this->sex=$sex;
//通過構造方法傳進來的$age給成員屬性$this->age賦初使值
$this->age=$age;
}
//這個人的說話方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
}
//這是一個解構函式,在物件銷燬前呼叫
function __destruct()
{
echo “再見”.$this->name.”<br>”;
}
}
//通過構造方法建立3個物件$p1、p2、$p3,分別傳入三個不同的實參為姓名、性別和年齡
$p1=new Person(“張三”,”男”, 20);
$p2=new Person(“李四”,”女”, 30);
$p3=new Person(“王五”,”男”, 40);
//下面訪問$p1物件中的說話方法
$p1->say();
//下面訪問$p2物件中的說話方法
$p2->say();
//下面訪問$p3物件中的說話方法
$p3->say();
?>
輸出結果為:
我的名子叫:張三 性別:男 我的年齡是:20
我的名子叫:李四 性別:女 我的年齡是:30
我的名子叫:王五 性別:男 我的年齡是:40
再見張三
再見李四
再見王五
9.封裝性
封裝性是面象物件程式設計中的三大特性之一,封裝性就是把物件的屬性和服務結合成一個獨立的相同單位,並儘可能隱蔽物件的內部細節,包含兩個含義:1.把物件的全部屬性和全部服務結合在一起,形成一個不可分割的獨立單位(即物件)。2.資訊隱蔽,即儘可能隱蔽物件的內部細節,對外形成一個邊界〔或者說形成一道屏障〕,只保留有限的對外介面使之與外部發生聯絡。
封裝的原則在軟體上的反映是:要求使物件以外的部分不能隨意存取物件的內部資料(屬性),從而有效的避免了外部錯誤對它的"交叉感染",使軟體錯誤能夠區域性化,大大減少查錯和排錯的難度。
用個例項來說明吧,假如某個人的物件中有年齡和工資等屬性,像這樣個人隱私的屬性是不想讓其它人隨意就能獲得到的,如果你不使用封裝,那麼別人想知道就能得到,但是如果你封裝上之後別人就沒有辦法獲得封裝的屬性,除非你自己把它說出去,否則別人沒有辦法得到。
在比如說,個人電腦都有一個密碼,不想讓其它人隨意的登陸,在你電腦裡面拷貝和貼上。還有就是像人這個物件,身高和年齡的屬性,只能是自己來增漲,不可以讓別人隨意的賦值等等。
使用private這個關鍵字來對屬性和方法進行封裝:
原來的成員:
var $name;//宣告人的姓名
var $sex;//宣告人的性別
var $age;//宣告人的年齡
function run(){…….}
改成封裝的形式:
private $name;//把人的姓名使用private關鍵字進行封裝
private $sex;//把人的性別使用private關鍵字進行封裝
private $age;//把人的年齡使用private關鍵字進行封裝
private function run(){……}//把人的走路方法使用private關鍵字進行封裝
注意:只要是成員屬性前面有其它的關鍵字就要去掉原有的關鍵字”var”.
通過private就可以把人的成員(成員屬性和成員方法)封裝上了。封裝上的成員就不能被類外面直接訪問了,只有物件內部自己可以訪問;下面的程式碼會產生錯誤:
class Person
{
//下面是人的成員屬性
private $name;//人的名子,被private封裝上了
private $sex;//人的性別, 被private封裝上了
private $age; //人的年齡, 被private封裝上了
//這個人可以說話的方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
}
//這個人可以走路的方法, 被private封裝上了
private function run()
{
echo "這個人在走路";
}
}
//例項化一個人的例項物件
$p1=new Person();
//試圖去給私有的屬性賦值,結果會發生錯誤
$p1->name="張三";
$p1->sex="男";
$p1->age=20;
//試圖去列印私有的屬性,結果會發生錯誤
echo $p1->name.”<br>”;
echo $p1->sex.”<br>”;
echo $p1->age.”<br>”
//試圖去列印私有的成員方法,結果會發生錯誤
$p1->run();
?>
輸出結果為:
Fatal error: Cannot access private property Person::$name
Fatal error: Cannot access private property Person::$sex
Fatal error: Cannot access private property Person::$age
Fatal error: Cannot access private property Person::$name
Fatal error: Call to private method Person::run() from context ''
從上面的例項可以看到, 私有的成員是不能被外部訪問的, 因為私有成員只能在本物件內部自己訪問,比如,$p1這個物件自己想把他的私有屬性說出去,在say()這個方法裡面訪問了私有屬性,這樣是可以。(沒有加任何訪問控制,預設的是public的,任何地方都可以訪問)
//這個人可以說話的方法, 說出自己的私有屬性,在這裡也可以訪問私有方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
//在這裡也可以訪問私有方法
//$this->run();
}
因為成員方法say()是公有的,所以我們在類的外部呼叫say()方法是可以的,改變上面的程式碼;
class Person
{
//下面是人的成員屬性
private $name;//人的名子,被private封裝上了
private $sex;//人的性別, 被private封裝上了
private $age; //人的年齡, 被private封裝上了
//定義一個構造方法引數為私有的屬性姓名$name、性別$sex和年齡$age進行賦值
function __construct($name, $sex, $age)
{
//通過構造方法傳進來的$name給私有成員屬性$this->name賦初使值
$this->name=$name;
//通過構造方法傳進來的$sex給私有成員屬性$this->sex賦初使值
$this->sex=$sex;
//通過構造方法傳進來的$age給私有成員屬性$this->age賦初使值
$this->age=$age;
}
//這個人可以說話的方法, 說出自己的私有屬性,在這裡也可以訪問私有方法
function say()
{
echo "我的名子叫:".$this->name." 性別:".$this->sex." 我的年齡是:".$this->age."<br>";
}
}
//通過構造方法建立3個物件$p1、p2、$p3,分別傳入三個不同的實參為姓名、性別和年齡
$p1=new Person(“張三”,”男”, 20);
$p2=new Person(“李四”,”女”, 30);
$p3=new Person(“王五”,”男”, 40);
//下面訪問$p1物件中的說話方法
$p1->say();
//下面訪問$p2物件中的說話方法
$p2->say();