近來參加了幾場PHP工程師的面試,但是筆試題答得都不理想,回來總結了一下失敗的原因,是沒看PHP手冊。幾家公司的PHP基礎面試題都可以在PHP手冊上找到。哎,現在才知道最好的面試寶典是PHP手冊。
下面是一些PHP面向對象基礎知識的摘錄,摘錄內容來自PHP5.1手冊。
1.類的變量成員叫做“屬性”,或者叫“字段”、“特征”,在本文檔統一稱為“屬性”。
2.屬性中的變量可以初始化,但是初始化的值必須是常數,這裡的常數是指php腳本在編譯階段時就為常數,而不是
在編譯階段之後在運行階段運算出的常數。
3.在類的成員方法裡面,可以通過$this->property(property是屬性名字)這種方式來訪問類的屬性、 方法,但是
要訪問類的靜態屬性或者在靜態方法裡面卻不能使用,而是使用self::$property。
4.在類的非靜態方法裡面可以使用偽變量$this,這個偽變量是調用該方法的實例化對象引用
5.常量的值必須是一個定值,不允許修改,且不能是變量,類屬性或其它操作(如函數調用)的結果。
<?php
class MyClass
{
const constant = 'constant value';
function showConstant() {
echo self::constant . "\n";
}
}
echo MyClass::constant . "\n";
$n=new MyClass();
$n->showConstant();
?>
6.構造函數的類會在每次創建對象時先調用此方法,所以非常適合在使用對象之前做一些初始化工作。
如果子類中定義了構造函數則不會暗中調用其父類的構造函數。要執行父類的構造函數,需要在子類的構造函數中
調用 parent::__construct()。
7.析構函數會在到某個對象的所有引用都被刪除或者當對象被顯式銷毀時執行。
父類的析構函數不會被引擎暗中調用。要執行父類的析構函數,必須在子類的析構函數體中顯式調用
parent::__destruct()。
析構函數在腳本關閉時調用,此時所有的頭信息已經發出。
試圖在析構函數中拋出一個異常會導致致命錯誤。
8.當擴展一個類,子類就會繼承父類的所有公有和保護方法。但是子類的方法會覆蓋父類的方法。
9.范圍解析操作符(::),可以用於訪問靜態成員、方法和常量
當在類的外部訪問這些靜態成員、方法和常量時,必須使用類的名字。
self 和 parent這兩個特殊的關鍵字是用於在類的內部對成員或方法進行訪問的。
10.當一個子類覆蓋其父類中的方法時,PHP 不會再執行父類中已被覆蓋的方法,直到子類中調用這些方法為止。這
種機制也作用於 構造函數和析構函數、重載 及 魔術 函數。
11.靜態變量和方法
聲明類成員或方法為static,就可以不實例化類而直接訪問。不能通過一個對象來訪問其中的靜態成員(靜態方法
除外)。
由於靜態方法不需要通過對象即可調用,所以偽變量$this在靜態方法中不可用。
靜態屬性不可以由對象通過->操作符來訪問。
用::方式調用一個非靜態方法會導致一個E_STRICT級別的錯誤。
就像其它所有的PHP靜態變量一樣,靜態屬性只能被初始化為一個字符值或一個常量,不能使用表達式。 所以你可
以把靜態屬性初始化為整型或數組,但不能指向另一個變量或函數返回值,也不能指向一個對象。
12.如果沒有指定“可見性”,屬性和方法默認為public。
13.抽象類
抽象類不能直接被實例化,你必須先繼承該抽象類,然後再實例化子類。抽象類中 至少要包含一個抽象方法。如果
類方法被聲明為抽象的,那麼其中就不能包括具體的功能實現。
繼承一個抽象類的時候,子類必須實現抽象類中的所有抽象方法;另外,這些方法的可見性 必須和抽象類中一樣(
或者更為寬松)。如果抽象類中某個抽象方法被聲明為protected,那麼子類中實現的方法就應該聲明為protected
或者public,而不 能定義為private。
應用示例:
abstract class AbstractClass
{
// 強制要求子類定義這些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
14.使用接口(interface),你可以指定某個類必須實現哪些方法,但不需要定義這些方法的具體內容。
我們可以通過interface來定義一個接口,就像定義一個標准的類一樣,但其中定義所有的方法都是空的。
接口中定義的所有方法都必須是public,這是接口的特性。
要實現一個接口,可以使用implements操作符。類中必須實現接口中定義的所有方法,否則 會報一個fatal錯誤。
如果要實現多個接口,可以用逗號來分隔多個接口的名稱。
實現多個接口時,接口中的方法不能有重名。
接口也可以繼承,通過使用extends操作符。
接口中也可以定義常量。接口常量和類常量的使用完全相同。 它們都是定值,不能被子類或子接口修改。
應用示例:
//接口定義
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
//使用接口
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
15.PHP5提供了一種迭代(iteration)對象的功能,就像使用數組那樣,可以通過foreach來遍歷對象中的屬性。
默認情況下,在外部迭代只能得到外部可見的屬性的值。
應用示例:
<?php
class MyClass
{
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3';
protected $protected = 'protected var';
private $private = 'private var';
function iterateVisible() {
echo "MyClass::iterateVisible:\n";
foreach($this as $key => $value) {
print "$key => $value\n";
}
}
}
$class = new MyClass();
foreach($class as $key => $value) {
print "$key => $value\n";
}
echo "\n";
$class->iterateVisible();
?>
16.設計模式
工廠模式(Factory)允許你在代碼執行時實例化對象。它之所以被稱為工廠模式是因為它負責“生產”對象。工廠
方法的參數是 你要生成的對象對應的類名稱。
單例模式(Singleton)用於為一個類生成一個唯一的對象。最常用的地方是數據庫連接。 使用單例模式生成一個
對象後,該對象可以被其它眾多對象所使用。
應用示例:
<?php
class Example
{
// 保存類實例在此屬性中
private static $instance;
// 構造方法聲明為private,防止直接創建對象
private function __construct()
{
echo 'I am constructed';
}
// singleton 方法
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
// Example類中的普通方法
public function bark()
{
echo 'Woof!';
}
// 阻止用戶復制對象實例
public function __clone()
{
trigger_error('Clone is not allowed.', E_USER_ERROR);
}
}
?>
這樣我們可以得到一個獨一無二的Example類的對象。
<?php
// 這個寫法會出錯,因為構造方法被聲明為private
$test = new Example;
// 下面將得到Example類的單例對象
$test = Example::singleton();
$test->bark();
// 復制對象將導致一個E_USER_ERROR.
$test_clone = clone $test;
?>
17.PHP 5 新增了一個 final 關鍵字。如果父類中的方法被聲明為final,則子類無法覆蓋該方法; 如果一個類被
聲明為final,則不能被繼承。
18.對象復制可以通過clone關鍵字來完成(如果對象中存在__clone()方法,會先被調用)。對象中的 __clone()
方法不能直接調用。
$copy_of_object = clone $object;
當對象被復制後,PHP5會對對象的所有屬性執行一個“淺復制”(shallow copy)。所有的屬性中的引用 仍然不
變,指向原來的變量。如果定義了__clone()方法,則新創建的對象(復制生成的對象)中的__clone()方法會被調
用, 可用於修改屬性的值(如果有必要的話)。
19.對象比較
當使用對比操作符(==)比較兩個對象變量時,比較的原則是:如果兩個對象的屬性和屬性值 都相等,而且兩個對象
是同一個類的實例,那麼這兩個對象變量相等。www.2cto.com
而如果使用全等操作符(===),這兩個對象變量一定要指向某個類的同一個實例(即同一個對象)。
20.對象和引用
php的引用是別名,就是兩個不同的變量名字指向相同的內容。在php5,一個對象變量已經不再保存整個對象的值。
只是保存一個標識符來訪問真正的對象內容。 當對象作為參數傳遞,作為結果返回,或者賦值給另外一個變量,另
外一個變量跟原來的不是引用的關系,只是他們都保存著同一個標識符的拷貝,這個標識符指向同一個對象的真正
內容