PHP面試常考內容之面向對象(3)

PHP面試專欄正式起更,每週1、3、五更新,提供最好最優質的PHP面試內容。
繼上一篇「PHP面試常考內容之面向對象(2)」發表後,今天更新面向對象的最後一篇(3)。須要(1),(2)的能夠直接點文字跳轉獲取。
PHP面試常考內容之面向對象(1)
整個面向對象文章的結構涉及的內容模塊有:php

1、面向對象與面向過程有什麼區別?
2、面向對象有什麼特徵?
3、什麼是構造函數和析構函數?
4、面向對象的做用域範圍有哪幾種?
5、PHP 中魔術方法有哪些?
6、什麼是對象克隆?
7、this、self和parent的區別是什麼?
8、抽象類與接口有什麼區別與聯繫?
9、PHP面向對象的常考面試題講解

關於PHP面向對象的內容將會被分爲三篇文章進行講解完整塊內容,第一篇主要講解一到四點內容,第二篇主要講解五到八的內容,第三篇圍繞第九點進行講解。html


如下正文的內容都來自《PHP程序員面試筆試真題解析》書籍,若是轉載請保留出處:程序員


9、PHP面向對象的常考面試題講解

【真題1】 什麼是面向對象?其主要特徵是什麼?

答案:面向對象是程序的一種設計方式,它是一種對現實世界的理解和抽象的方法,它能夠提升程序的重用性,讓程序結構更加清晰。
面向對象的主要特徵爲:封裝、繼承、多態。面試


【真題2】 能夠得到對象的類名的函數是( )。

A.get_class_name B.get_class C.class_exists D.get_class_vars
答案:B。
PHP中獲取對象的類名函數是get_class()。因此,選項B正確。
對於選項A,不存在該方法。因此,選項A錯誤。
對於選項C,class_exists()函數能夠檢查類是否存在。因此,選項C錯誤。
對於選項D,get_class_vars()函數能夠獲取類的默認屬性。因此,選項D錯誤。
因此,本題的答案是B。數據庫


【真題3】 請簡單說明PHP的垃圾收集機制。

答案:在PHP中,當沒有任何變量指向該對象時,該對象變爲垃圾將會在內存中被銷燬,能夠防止內存溢出。內存中對變量有引用計數,當計數到0時變量被銷燬。編程


【真題4】多態與方法重寫有什麼關係?

答案:多態是指一個類能夠被多個類繼承,每一個子類均可以對父類方法進行重寫,每一個類裏的同名方法能夠實現不一樣的功能從而表現出多種形態,它加強了軟件的靈活性和重用性。
重寫是子類對父類中的方法進行改寫。它們的關係是重寫讓類具有多態性。segmentfault


【真題5】面向對象幾大原則是什麼?

答案:面向對象存在五大基本原則,分別是:單一職責原則、開放封閉原則、替換原則、依賴原則、接口分離原則等。
(1)單一職責原則
所謂單一職責原則,即一個類最好只作一件事。爲了提升內聚性減小引發變化,單一原則是低耦合、高內聚的面向原則上的引伸。
(2)開放封閉原則
軟件的功能應該是可擴展的,儘量減小修改,由於修改程序,可能會對原來的程序形成影響。雖然建議儘量不修改程序,可是容許經過添加功能來減小修改。
(3)替換原則
只有子類可以替換基類,在繼承機制的約束規範中,子類替換基類時,能夠保證運行期內識別子類,保證繼承複用。
(4)依賴倒置原則
高層模塊不依賴底層模塊,兩者都依賴於抽象,抽象不依賴於實體,而實體依賴於抽象。模塊間的依賴是經過抽象方法發生的,實現類中不發生直接的依賴關係,而依賴關係是經過接口或抽象類產生的。即接口或抽象類不依賴於實現類,而實現類依賴於接口和抽象類。這種依賴倒置原則能夠有效地減小類之間的耦合性,提升系統的穩定性,減小併發引發的風險,提升代碼的可讀性和可維護性。
(5)接口隔離原則
建議開發使用多個小的、專門的接口,避免使用一個大的總接口。即每個功能有一個專門的功能接口,須要用到才調用,不須要所有功能彙總到一個接口,這樣能夠提升代碼的靈活性,下降類之間的耦合性,提升穩定性。數組


【真題6】如下有關PHP高級特性的說法中,正確的是( )。

A.能夠定義一個類去實現預約義接口Iterator,而後就能像訪問數組同樣訪問這個類建立的對象
B.spl_autoload_register()提供了一種更加靈活的方式來實現類的自動加載,再也不建議使用_autoload()函數
C.PHP在對象中調用一個不可訪問方法時,invoke()方法會被自動調用
D.匿名函數也叫閉包函數,經常使用做回調函數參數的值,可是不能做爲變量的值來使用
答案:B。
對於選項A,只有ArrayAccess可以提供像訪問數組同樣訪問這個對象的接口,不能定義一個類或預約義接口Iterator去實現這個功能。因此,選項A錯誤。
對於選項B,由於能夠經過spl_autoload_register()函數建立autoload函數的隊列,按定義順序逐個執行,比_autoload()函數只能夠定義一次使用更方便,因此不建議使用_autoload()函數。因此,選項B正確。
對於選項C,_call方法是在建立一個類實例化後就能夠直接調用對象使用,當調用的方法不可訪問或沒有權限訪問時,會自動調用_call方法。因此,選項C錯誤。
對於選項D,匿名函數是能夠賦值給變量的。因此,選項D錯誤。
因此,本題的答案是B。緩存


【真題7】__autoload()函數的工做原理是什麼?

答案:使用這個魔術函數的基本條件是,類文件的文件名要和類的名字保持一致。
當程序執行到實例化某個類時,若是在實例化前沒有引入這個類文件,那麼就自動執行__autoload()函數。這個函數根據實例化的類名去查找這個類的路徑,一旦找到這個類後就會經過執行include或require載入該類,從而保證程序可以繼續執行。若是沒有找到,那麼報錯。閉包


【真題8】如下關於PHP命名空間的說法中,不正確的是( )。

A.訪問任意全局類、函數或常量,均可以使用徹底限定名稱,例如strlen()或Exception或INI_ALL
B.關鍵字 namespace可用來顯式訪問當前命名空間或子命名空間中的元素,它等價於類中的 this 操做符
C.任意合法的PHP代碼均可以包含在命名空間中,但只有三種類型的代碼受命名空間的影響,它們是類、函數和常量
D.常量__NAMESPACE__的值是當前命名空間名稱的字符串。若是是在全局中,那麼它不包括任何命名空間中的代碼,自己是一個空字符串
答案:B。
namespace關鍵字是用來聲明命名空間用的,它並不能等價於this操做符的功能。因此,選項B說法不對。
因此,本題的答案是B。

【真題9】如下代碼的運行結果是( )。

<?php    
    class Person{
       var $name;
    }
    $a = new Person();
    $a->name = "張三";
    $b = $a;
    $b->name = "李四";
    echo $a->name;
?>

A.張三 B.李四 C.Null D.什麼都沒有
答案:B。
首先$a實例化Person類,把張三賦值給類內的變量name,把對象張三的值給了$b,經過$b去修改類內name的值爲李四,因此最後輸出Person類內的name,輸出獲得結果李四。因此,選項B正確,選項A、選項C、選項D錯誤。
因此,本題的答案是B。


【真題10】下面說法錯誤的是( )。

A.若是一個類的成員前面有訪問修飾符private,那麼這些成員不能被繼承,在類的外部不可見。但若是成員被指定爲protected和public,那麼能夠被繼承,在類的外部也是可見的
B.PHP5中,final關鍵字能夠禁止繼承和重載
C.PHP5中,析構函數的名稱是__destruct(),而且不能有任何參數
D.繼承接口的類必須實現接口中聲明的全部方法,在PHP中,若是繼承接口的類沒有實現接口中的方法,那麼將會產生一個致命錯誤
答案:A。
對於選項A,private修飾的成員是不能夠被繼承的,protected的成員是能夠被繼承的,可是在外部不可見,選項A說法錯誤,因此,選項A正確。
對於選項B,final關鍵字的方法是禁止被繼承和重載的,選項B說法正確,因此選項B錯誤。
對於選項C,析構函數不能有參數,選項C說法正確,因此,選項C錯誤。
對於選項D,繼承接口的類沒有實現接口中的方法是會產生錯誤的,選項D說法正確,因此,選項D錯誤。
因此,本題的答案是A。


本身整理了一篇「 我的編程6年的心得——如何學好編程?」的文章,關注公衆號:「 琉憶編程庫」,回覆:「 學好」,我發給你。

【真題11】 定義類成員的訪問權限控制符有哪些?默認修飾符是什麼?

答案:類成員的訪問修飾符有public、private、protected,主要用來修飾類中的成員屬性和方法。public是公共類型,容許在類的內部或子類中使用,也能夠在類外部被訪問。private是私有類型,只能在類的內部被使用,不能被繼承使用。protected是保護類型,只能在類的內部或子類中使用。若是不使用public、private、protected等關鍵字修飾方法或屬性,那麼可使用var關鍵字,它的功能等同於public,能夠在類內或類外被調用,也能夠被繼承使用。
其中,PHP默認的修飾符是public,即公有類型。
類前面只能加final、abstract關鍵字,被final修飾的屬性或方法是不能被繼承的,只能在當前類中使用,abstract定義的類或方法,叫做抽象類或抽象方法。
屬性前面:必須有訪問修飾符(private,protected,public,var)。


【真題12】 PHP的魔術方法包含哪些(越多越好)?在什麼狀況下被自動調用?

答案:PHP可用的魔術方法會在特定狀況下被自動調用,可是前提是特定的條件被觸發,而且這些魔術方法能夠在類中做爲方法。
PHP的魔術方法有:
1)_construct():構造函數,建立對象時自動被調用。
2)_destruct():析構函數,對象的全部引用都被刪除或者當對象被顯式銷燬時執行。
3)__clone():克隆函數,調用clone方法時自動調用。
4)__set():當程序試圖寫入一個不存在或不可見的成員變量時自動調用。該函數在類中定義時必須有兩個參數:變量名和變量值。
5)__get():當程序調用一個未定義或不可見的成員變量時自動調用__get()來讀取變量值。定義時必有有一個參數:變量名。
6)__call():當程序試圖調用不存在或不可見的成員方法時,自動調用__call()。__call()方法通常用於監視錯誤的方法調用。爲了不當調用的方法不存在時產生錯誤,可使用__call()方法來避免。該方法包含兩個參數:方法名和方法參數。其中,方法參數以數組形式存在。
7)__sleep():使用serialize()實現序列化對象時,先調用該方法,能夠用來清除對象並返回一個該對象中全部變量的數組。
8)__wakeup():使用unserialize()還原一個被序列化的對象時,先執行該方法,恢復在序列化中可能丟失的數據庫鏈接及相關工做。
9)__toString():當使用echo或print輸出對象時,將對象轉化爲字符串。
10)__autoload():調用未被實例化的類時,自動調用,在指定路徑下查找和該類名稱相同的文件。


【真題13】 $this、self和parent這三個關鍵詞分別表明什麼?在哪些場合下使用?

答案:$this表示當前對象,在當前類中能夠經過->符調用類內的屬性和方法。
self表示當前類,只能經過self的形式(「self::方法或屬性」)調用類內的方法。
parent表示當前類的父類,調用父類內的方法只能使用「parent::」形式調用。

【真題14】下面關於面向對象的描述中,錯誤的是( )。

A.父類的構造函數與析構函數不會自動被調用
B.成員變量須要用public、protected、private修飾,在定義變量時再也不須要var關鍵字
C.父類中定義的靜態成員,不能夠在子類中直接調用
D.包含抽象方法的類必須爲抽象類,抽象類不能被實例化
答案:A。
對於選項A,子類繼承父類,若是子類沒有構造函數和析構函數,那麼實例化子類時會自動調用父類的構造函數和析構函數;但若是子類只有構造函數沒有析構函數時,那麼實例化子類時,自動調用的是子類的構造函數,銷燬對象時調用父類的析構函數;若是子類沒有構造函數只有析構函數,那麼實例化子類時會自動調用父類的構造函數,銷燬對象時調用子類的析構函數,選項A說法不徹底。因此,選項A正確。
對於選項B,成員變量使用了public、protected、private修飾定義變量時是不須要var關鍵字的,選項B說法正確。因此,選項B錯誤。
對於選項C,父類中的靜態成員,子類中是不能夠直接訪問的,選項B說法正確。因此,選項C錯誤。
對於選項D,一個包含抽象方法的類必須是抽象類,而且抽象類不能被實例化。選項D說法正確。因此,選項D錯誤。
因此,本題的答案是A。


【真題15】 在PHP中,若是派生類與父類有相同名字的函數,那麼派生類的函數會替換父類的函數,有以下程序代碼:

<?php
    class A {
          function disName(){
            echo "Picachu";
      }
    }
    class B extends A {
       var $tmp='';
       function disName(){
          echo "Doraemon";
       }
    }
    $cartoon = new B;
    $cartoon->disName();
?>

上述代碼的運行結果爲( )。
A.tmp B.Picachu C.disName
D.Doraemon E.無輸出
答案:D。
當派生類繼承父類時,若是經過實例化一個派生類的對象來訪問對象的方法時,派生類不存在父類中的方法,那麼執行父類中的方法。若是派生類和父類存在相同名字的方法,那麼派生類的方法會覆蓋父類方法,執行派生類的方法。因此,本題中能夠執行派生類的disName()方法。因此,選項D正確,選項A、選項B、選項C、選項E錯誤。
因此,本題的答案是D。


【真題16】什麼是抽象類和接口?抽象類和接口有什麼不一樣和類似的地方?

答案:被關鍵字abstract修飾的類叫做抽象類,抽象類是不能被實例化的。被abstract修飾的方法爲抽象方法,一個類只要有一個抽象方法,這個類必定是抽象類。
接口是經過關鍵字interface來定義的,能夠指定某個類必須實現哪些方法,但不須要定義這些方法的具體實現。PHP類只支持是單重繼承的,但經過接口能夠實現PHP類的多重繼承。
抽象類和接口的不一樣和類似的地方以下所示。
1)抽象類是一種不能被實例化的類,只能做爲其餘類的父類來使用。
2)抽象類是經過關鍵字abstract來聲明的。
3)抽象類與普通類類似,都包含成員變量和成員方法,二者的區別在於,抽象類中至少要包含一個抽象方法。
4)抽象方法沒有方法體,該方法就是要被子類重寫的。
5)抽象方法的格式爲:abstract function abstractMethod()。
6)由於PHP中只支持單重繼承,因此若是想實現多重繼承,那麼就要使用接口。也就是說,子類能夠實現多個接口。
7)接口類是經過interface關鍵字來聲明的,接口類中的成員變量和方法都是public的,能夠不用顯式地使用public來修飾。
8)接口中的方法沒有方法體。接口中的方法就是要被子類繼承實現的。
9)子類繼承抽象類使用extends關鍵字,子類實現接口使用implements關鍵字。


【真題17】用類編程實現:Stu類中有兩個私有屬性name和sex,有兩個公有方法,setName()和setSex()參數自定,方法可實現對兩個私有屬性進行修改。在實例化類時要求對私有屬性能初始化。

答案:實現代碼以下:

<?php
    Class Stu{
       private $name;
       private $sex;
       public function setName($name){
          $this->name = $name;
       }
       public function setSex($sex){
          $this->sex = $sex;
       }
    }
?>

【真題18】 假若有一個類Person,實例化(new)一個對象$p,那麼如下使用對象$p調用Person類中的getInfo方法的寫法中,正確的是( )。

A.$p=>getInfo(); B.$this->getInfo();
C.$p->getInfo(); D.$p::getInfo();
參考答案:C。
分析:「::」主要用於訪問類中的靜態成員,「->」主要用於訪問類中的變量和方法,「=>」主要應用在數組中的key和value映射時使用。因此,選項A、選項B、選項D錯誤,選項C正確。


【真題19】php中public、protected、private三種訪問控制模式的區別是什麼?

參考答案:php中public、protected、private三種訪問控制模式的區別以下:
訪 問 模 式 描 述
public 共有,任何地方均可以訪問
protected 繼承,只能在本類或子類中訪問,在其餘地方不能使用
private 私有,只能在本類中訪問,在其餘地方不能使用


【真題20】 在PHP面向對象中,下面關於final修飾符的描述中,錯誤的是( )。

A.使用final標識的類不能被繼承
B.在類中使用final標識的成員方法,在子類中不能被覆蓋
C.不能使用final標識成員屬性
D.使用final標識的成員屬性,不能在子類中再次定義
參考答案:D。
分析:由於final只能修飾類與方法,不能修飾類的屬性。因此,選項D錯誤。

PS:因爲真題較多,僅羅列PHP面向對象筆試中常常遇到的20道考題!


至此本週(2019-2-11 至 2019-2-15 的面向對象專題已更新完畢,以上的內容只是摘取了PHP面向對象中最常考的內容,個別內容沒有羅列能夠從原書中獲取。)感謝你們的支持!

預告:下週(2019-2.18 —— 2.22)更新「PHP面試常考內容之Memcache和Redis緩存的」專題,敬請期待。

以上內容摘自《PHP程序員面試筆試真題解析》書籍,該書已在天貓京東噹噹等電商平臺銷售。
圖片描述

更多PHP相關的面試知識、考題能夠關注公衆號獲取:琉憶編程庫
圖片描述

對本文有什麼問題或建議均可以進行留言,將不斷完善追求極致,感謝大家的支持。

相關文章
相關標籤/搜索