PHP面试常考内容之面向对象(3)
PHP面試專欄正式起更,每周一、三、五更新,提供最好最優(yōu)質(zhì)的PHP面試內(nèi)容。
繼上一篇“PHP面試常考內(nèi)容之面向?qū)ο?#xff08;2)”發(fā)表后,今天更新面向?qū)ο蟮淖詈笠黄?#xff08;3)。需要(1),(2)的可以直接點文字跳轉(zhuǎn)獲取。
PHP面試常考內(nèi)容之面向?qū)ο?#xff08;1)
整個面向?qū)ο笪恼碌慕Y(jié)構(gòu)涉及的內(nèi)容模塊有:
二、面向?qū)ο笥惺裁刺卣?#xff1f;
三、什么是構(gòu)造函數(shù)和析構(gòu)函數(shù)?
四、面向?qū)ο蟮淖饔糜蚍秶心膸追N?
五、PHP 中魔術(shù)方法有哪些?
六、什么是對象克隆?
七、this、self和parent的區(qū)別是什么?
八、抽象類與接口有什么區(qū)別與聯(lián)系?
九、PHP面向?qū)ο蟮某?济嬖囶}講解
關(guān)于PHP面向?qū)ο蟮膬?nèi)容將會被分為三篇文章進行講解完整塊內(nèi)容,第一篇主要講解一到四點內(nèi)容,第二篇主要講解五到八的內(nèi)容,第三篇圍繞第九點進行講解。
以下正文的內(nèi)容都來自《PHP程序員面試筆試真題解析》書籍,如果轉(zhuǎn)載請保留出處:
九、PHP面向?qū)ο蟮某?济嬖囶}講解
【真題1】 什么是面向?qū)ο?#xff1f;其主要特征是什么?
答案:面向?qū)ο笫浅绦虻囊环N設(shè)計方式,它是一種對現(xiàn)實世界的理解和抽象的方法,它可以提高程序的重用性,讓程序結(jié)構(gòu)更加清晰。
面向?qū)ο蟮闹饕卣鳛?#xff1a;封裝、繼承、多態(tài)。
【真題2】 可以獲得對象的類名的函數(shù)是( )。
A.get_class_name B.get_class C.class_exists D.get_class_vars
答案:B。
PHP中獲取對象的類名函數(shù)是get_class()。所以,選項B正確。
對于選項A,不存在該方法。所以,選項A錯誤。
對于選項C,class_exists()函數(shù)可以檢查類是否存在。所以,選項C錯誤。
對于選項D,get_class_vars()函數(shù)可以獲取類的默認屬性。所以,選項D錯誤。
所以,本題的答案是B。
【真題3】 請簡單說明PHP的垃圾收集機制。
答案:在PHP中,當(dāng)沒有任何變量指向該對象時,該對象變?yōu)槔鴮趦?nèi)存中被銷毀,可以防止內(nèi)存溢出。內(nèi)存中對變量有引用計數(shù),當(dāng)計數(shù)到0時變量被銷毀。
【真題4】多態(tài)與方法重寫有什么關(guān)系?
答案:多態(tài)是指一個類可以被多個類繼承,每個子類都可以對父類方法進行重寫,每個類里的同名方法可以實現(xiàn)不同的功能從而表現(xiàn)出多種形態(tài),它增強了軟件的靈活性和重用性。
重寫是子類對父類中的方法進行改寫。它們的關(guān)系是重寫讓類具備多態(tài)性。
【真題5】面向?qū)ο髱状笤瓌t是什么?
答案:面向?qū)ο蟠嬖谖宕蠡驹瓌t,分別是:單一職責(zé)原則、開放封閉原則、替換原則、依賴原則、接口分離原則等。
(1)單一職責(zé)原則
所謂單一職責(zé)原則,即一個類最好只做一件事。為了提高內(nèi)聚性減少引起變化,單一原則是低耦合、高內(nèi)聚的面向原則上的引申。
(2)開放封閉原則
軟件的功能應(yīng)該是可擴展的,盡可能減少修改,因為修改程序,可能會對原來的程序造成影響。雖然建議盡可能不修改程序,但是允許通過添加功能來減少修改。
(3)替換原則
只有子類能夠替換基類,在繼承機制的約束規(guī)范中,子類替換基類時,可以保證運行期內(nèi)識別子類,保證繼承復(fù)用。
(4)依賴倒置原則
高層模塊不依賴底層模塊,二者都依賴于抽象,抽象不依賴于實體,而實體依賴于抽象。模塊間的依賴是通過抽象方法發(fā)生的,實現(xiàn)類中不發(fā)生直接的依賴關(guān)系,而依賴關(guān)系是通過接口或抽象類產(chǎn)生的。即接口或抽象類不依賴于實現(xiàn)類,而實現(xiàn)類依賴于接口和抽象類。這種依賴倒置原則可以有效地減少類之間的耦合性,提高系統(tǒng)的穩(wěn)定性,減少并發(fā)引起的風(fēng)險,提高代碼的可讀性和可維護性。
(5)接口隔離原則
建議開發(fā)使用多個小的、專門的接口,避免使用一個大的總接口。即每一個功能有一個專門的功能接口,需要用到才調(diào)用,不需要全部功能匯總到一個接口,這樣可以提高代碼的靈活性,降低類之間的耦合性,提高穩(wěn)定性。
【真題6】以下有關(guān)PHP高級特性的說法中,正確的是( )。
A.可以定義一個類去實現(xiàn)預(yù)定義接口Iterator,然后就能像訪問數(shù)組一樣訪問這個類創(chuàng)建的對象
B.spla_utoload_register()提供了一種更加靈活的方式來實現(xiàn)類的自動加載,不再建議使用_autoload()函數(shù)
C.PHP在對象中調(diào)用一個不可訪問方法時,invoke()方法會被自動調(diào)用
D.匿名函數(shù)也叫閉包函數(shù),常用作回調(diào)函數(shù)參數(shù)的值,但是不能作為變量的值來使用
答案:B。
對于選項A,只有ArrayAccess能夠提供像訪問數(shù)組一樣訪問這個對象的接口,不能定義一個類或預(yù)定義接口Iterator去實現(xiàn)這個功能。所以,選項A錯誤。
對于選項B,因為可以通過spla_utoload_register()函數(shù)創(chuàng)建autoload函數(shù)的隊列,按定義順序逐個執(zhí)行,比_autoload()函數(shù)只可以定義一次使用更方便,所以不建議使用_autoload()函數(shù)。所以,選項B正確。
對于選項C,_call方法是在創(chuàng)建一個類實例化后就可以直接調(diào)用對象使用,當(dāng)調(diào)用的方法不可訪問或沒有權(quán)限訪問時,會自動調(diào)用_call方法。所以,選項C錯誤。
對于選項D,匿名函數(shù)是可以賦值給變量的。所以,選項D錯誤。
所以,本題的答案是B。
【真題7】__autoload()函數(shù)的工作原理是什么?
答案:使用這個魔術(shù)函數(shù)的基本條件是,類文件的文件名要和類的名字保持一致。
當(dāng)程序執(zhí)行到實例化某個類時,如果在實例化前沒有引入這個類文件,那么就自動執(zhí)行__autoload()函數(shù)。這個函數(shù)根據(jù)實例化的類名去查找這個類的路徑,一旦找到這個類后就會通過執(zhí)行include或require載入該類,從而保證程序能夠繼續(xù)執(zhí)行。如果沒有找到,那么報錯。
【真題8】以下關(guān)于PHP命名空間的說法中,不正確的是( )。
A.訪問任意全局類、函數(shù)或常量,都可以使用完全限定名稱,例如strlen()或Exception或INI_ALL
B.關(guān)鍵字 namespace可用來顯式訪問當(dāng)前命名空間或子命名空間中的元素,它等價于類中的 this 操作符?
C.任意合法的PHP代碼都可以包含在命名空間中,但只有三種類型的代碼受命名空間的影響,它們是類、函數(shù)和常量
D.常量__NAMESPACE__的值是當(dāng)前命名空間名稱的字符串。如果是在全局中,那么它不包括任何命名空間中的代碼,本身是一個空字符串
答案:B。
namespace關(guān)鍵字是用來聲明命名空間用的,它并不能等價于this操作符的功能。所以,選項B說法不對。
所以,本題的答案是B。
【真題9】以下代碼的運行結(jié)果是( )。
<?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類,把張三賦值給類內(nèi)的變量name,把對象張三的值給了$b,通過$b去修改類內(nèi)name的值為李四,所以最后輸出Person類內(nèi)的name,輸出得到結(jié)果李四。所以,選項B正確,選項A、選項C、選項D錯誤。
所以,本題的答案是B。
【真題10】下面說法錯誤的是( )。
A.如果一個類的成員前面有訪問修飾符private,那么這些成員不能被繼承,在類的外部不可見。但如果成員被指定為protected和public,那么可以被繼承,在類的外部也是可見的
B.PHP5中,final關(guān)鍵字可以禁止繼承和重載
C.PHP5中,析構(gòu)函數(shù)的名稱是__destruct(),并且不能有任何參數(shù)
D.繼承接口的類必須實現(xiàn)接口中聲明的所有方法,在PHP中,如果繼承接口的類沒有實現(xiàn)接口中的方法,那么將會產(chǎn)生一個致命錯誤
答案:A。
對于選項A,private修飾的成員是不可以被繼承的,protected的成員是可以被繼承的,但是在外部不可見,選項A說法錯誤,所以,選項A正確。
對于選項B,final關(guān)鍵字的方法是禁止被繼承和重載的,選項B說法正確,所以選項B錯誤。
對于選項C,析構(gòu)函數(shù)不能有參數(shù),選項C說法正確,所以,選項C錯誤。
對于選項D,繼承接口的類沒有實現(xiàn)接口中的方法是會產(chǎn)生錯誤的,選項D說法正確,所以,選項D錯誤。
所以,本題的答案是A。
自己整理了一篇“個人編程6年的心得——如何學(xué)好編程?”的文章,關(guān)注公眾號:“琉憶編程庫”,回復(fù):“學(xué)好”,我發(fā)給你。
【真題11】 定義類成員的訪問權(quán)限控制符有哪些?默認修飾符是什么?
答案:類成員的訪問修飾符有public、private、protected,主要用來修飾類中的成員屬性和方法。public是公共類型,允許在類的內(nèi)部或子類中使用,也可以在類外部被訪問。private是私有類型,只能在類的內(nèi)部被使用,不能被繼承使用。protected是保護類型,只能在類的內(nèi)部或子類中使用。如果不使用public、private、protected等關(guān)鍵字修飾方法或?qū)傩?#xff0c;那么可以使用var關(guān)鍵字,它的功能等同于public,可以在類內(nèi)或類外被調(diào)用,也可以被繼承使用。
其中,PHP默認的修飾符是public,即公有類型。
類前面只能加final、abstract關(guān)鍵字,被final修飾的屬性或方法是不能被繼承的,只能在當(dāng)前類中使用,abstract定義的類或方法,叫作抽象類或抽象方法。
屬性前面:必須有訪問修飾符(private,protected,public,var)。
【真題12】 PHP的魔術(shù)方法包含哪些(越多越好)?在什么情況下被自動調(diào)用?
答案:PHP可用的魔術(shù)方法會在特定情況下被自動調(diào)用,但是前提是特定的條件被觸發(fā),并且這些魔術(shù)方法可以在類中作為方法。
PHP的魔術(shù)方法有:
1)_construct():構(gòu)造函數(shù),創(chuàng)建對象時自動被調(diào)用。
2)_destruct():析構(gòu)函數(shù),對象的所有引用都被刪除或者當(dāng)對象被顯式銷毀時執(zhí)行。
3)__clone():克隆函數(shù),調(diào)用clone方法時自動調(diào)用。
4)__set():當(dāng)程序試圖寫入一個不存在或不可見的成員變量時自動調(diào)用。該函數(shù)在類中定義時必須有兩個參數(shù):變量名和變量值。
5)__get():當(dāng)程序調(diào)用一個未定義或不可見的成員變量時自動調(diào)用__get()來讀取變量值。定義時必有有一個參數(shù):變量名。
6)__call():當(dāng)程序試圖調(diào)用不存在或不可見的成員方法時,自動調(diào)用__call()。__call()方法一般用于監(jiān)視錯誤的方法調(diào)用。為了避免當(dāng)調(diào)用的方法不存在時產(chǎn)生錯誤,可以使用__call()方法來避免。該方法包含兩個參數(shù):方法名和方法參數(shù)。其中,方法參數(shù)以數(shù)組形式存在。
7)__sleep():使用serialize()實現(xiàn)序列化對象時,先調(diào)用該方法,可以用來清除對象并返回一個該對象中所有變量的數(shù)組。
8)__wakeup():使用unserialize()還原一個被序列化的對象時,先執(zhí)行該方法,恢復(fù)在序列化中可能丟失的數(shù)據(jù)庫連接及相關(guān)工作。
9)__toString():當(dāng)使用echo或print輸出對象時,將對象轉(zhuǎn)化為字符串。
10)__autoload():調(diào)用未被實例化的類時,自動調(diào)用,在指定路徑下查找和該類名稱相同的文件。
【真題13】 $this、self和parent這三個關(guān)鍵詞分別代表什么?在哪些場合下使用?
答案:$this表示當(dāng)前對象,在當(dāng)前類中可以通過->符調(diào)用類內(nèi)的屬性和方法。
self表示當(dāng)前類,只能通過self的形式(“self::方法或?qū)傩浴?#xff09;調(diào)用類內(nèi)的方法。
parent表示當(dāng)前類的父類,調(diào)用父類內(nèi)的方法只能使用“parent::”形式調(diào)用。
【真題14】下面關(guān)于面向?qū)ο蟮拿枋鲋?#xff0c;錯誤的是( )。
A.父類的構(gòu)造函數(shù)與析構(gòu)函數(shù)不會自動被調(diào)用
B.成員變量需要用public、protected、private修飾,在定義變量時不再需要var關(guān)鍵字
C.父類中定義的靜態(tài)成員,不可以在子類中直接調(diào)用
D.包含抽象方法的類必須為抽象類,抽象類不能被實例化
答案:A。
對于選項A,子類繼承父類,如果子類沒有構(gòu)造函數(shù)和析構(gòu)函數(shù),那么實例化子類時會自動調(diào)用父類的構(gòu)造函數(shù)和析構(gòu)函數(shù);但如果子類只有構(gòu)造函數(shù)沒有析構(gòu)函數(shù)時,那么實例化子類時,自動調(diào)用的是子類的構(gòu)造函數(shù),銷毀對象時調(diào)用父類的析構(gòu)函數(shù);如果子類沒有構(gòu)造函數(shù)只有析構(gòu)函數(shù),那么實例化子類時會自動調(diào)用父類的構(gòu)造函數(shù),銷毀對象時調(diào)用子類的析構(gòu)函數(shù),選項A說法不完全。所以,選項A正確。
對于選項B,成員變量使用了public、protected、private修飾定義變量時是不需要var關(guān)鍵字的,選項B說法正確。所以,選項B錯誤。
對于選項C,父類中的靜態(tài)成員,子類中是不可以直接訪問的,選項B說法正確。所以,選項C錯誤。
對于選項D,一個包含抽象方法的類必須是抽象類,并且抽象類不能被實例化。選項D說法正確。所以,選項D錯誤。
所以,本題的答案是A。
【真題15】 在PHP中,如果派生類與父類有相同名字的函數(shù),那么派生類的函數(shù)會替換父類的函數(shù),有如下程序代碼:
<?phpclass A {function disName(){echo "Picachu";}}class B extends A {var $tmp='';function disName(){echo "Doraemon";}}$cartoon = new B;$cartoon->disName(); ?>上述代碼的運行結(jié)果為( )。
A.tmp B.Picachu C.disName?
D.Doraemon E.無輸出
答案:D。
當(dāng)派生類繼承父類時,如果通過實例化一個派生類的對象來訪問對象的方法時,派生類不存在父類中的方法,那么執(zhí)行父類中的方法。如果派生類和父類存在相同名字的方法,那么派生類的方法會覆蓋父類方法,執(zhí)行派生類的方法。所以,本題中可以執(zhí)行派生類的disName()方法。所以,選項D正確,選項A、選項B、選項C、選項E錯誤。
所以,本題的答案是D。
【真題16】什么是抽象類和接口?抽象類和接口有什么不同和相似的地方?
答案:被關(guān)鍵字abstract修飾的類叫作抽象類,抽象類是不能被實例化的。被abstract修飾的方法為抽象方法,一個類只要有一個抽象方法,這個類一定是抽象類。
接口是通過關(guān)鍵字interface來定義的,可以指定某個類必須實現(xiàn)哪些方法,但不需要定義這些方法的具體實現(xiàn)。PHP類只支持是單重繼承的,但通過接口可以實現(xiàn)PHP類的多重繼承。
抽象類和接口的不同和相似的地方如下所示。
1)抽象類是一種不能被實例化的類,只能作為其他類的父類來使用。
2)抽象類是通過關(guān)鍵字abstract來聲明的。
3)抽象類與普通類相似,都包含成員變量和成員方法,兩者的區(qū)別在于,抽象類中至少要包含一個抽象方法。
4)抽象方法沒有方法體,該方法就是要被子類重寫的。
5)抽象方法的格式為:abstract function abstractMethod()。
6)因為PHP中只支持單重繼承,所以如果想實現(xiàn)多重繼承,那么就要使用接口。也就是說,子類可以實現(xiàn)多個接口。
7)接口類是通過interface關(guān)鍵字來聲明的,接口類中的成員變量和方法都是public的,可以不用顯式地使用public來修飾。
8)接口中的方法沒有方法體。接口中的方法就是要被子類繼承實現(xiàn)的。
9)子類繼承抽象類使用extends關(guān)鍵字,子類實現(xiàn)接口使用implements關(guān)鍵字。
【真題17】用類編程實現(xiàn):Stu類中有兩個私有屬性name和sex,有兩個公有方法,setName()和setSex()參數(shù)自定,方法可實現(xiàn)對兩個私有屬性進行修改。在實例化類時要求對私有屬性能初始化。
答案:實現(xiàn)代碼如下:
<?phpClass Stu{private $name;private $sex;public function setName($name){$this->name = $name;}public function setSex($sex){$this->sex = $sex;}} ?>【真題18】 假如有一個類Person,實例化(new)一個對象$p,那么以下使用對象$p調(diào)用Person類中的getInfo方法的寫法中,正確的是( )。
A.$p=>getInfo(); B.$this->getInfo();?
C.$p->getInfo(); D.$p::getInfo();
參考答案:C。
分析:“::”主要用于訪問類中的靜態(tài)成員,“->”主要用于訪問類中的變量和方法,“=>”主要應(yīng)用在數(shù)組中的key和value映射時使用。所以,選項A、選項B、選項D錯誤,選項C正確。
【真題19】php中public、protected、private三種訪問控制模式的區(qū)別是什么?
參考答案:php中public、protected、private三種訪問控制模式的區(qū)別如下:
訪 問 模 式 描 述
public 共有,任何地方都可以訪問
protected 繼承,只能在本類或子類中訪問,在其他地方不能使用
private 私有,只能在本類中訪問,在其他地方不能使用
【真題20】 在PHP面向?qū)ο笾?#xff0c;下面關(guān)于final修飾符的描述中,錯誤的是( )。
A.使用final標(biāo)識的類不能被繼承?
B.在類中使用final標(biāo)識的成員方法,在子類中不能被覆蓋
C.不能使用final標(biāo)識成員屬性?
D.使用final標(biāo)識的成員屬性,不能在子類中再次定義
參考答案:D。
分析:因為final只能修飾類與方法,不能修飾類的屬性。所以,選項D錯誤。
PS:由于真題較多,僅羅列PHP面向?qū)ο蠊P試中經(jīng)常遇到的20道考題!
至此本周(2019-2-11 至 2019-2-15 的面向?qū)ο髮n}已更新完畢,以上的內(nèi)容只是摘取了PHP面向?qū)ο笾凶畛?嫉膬?nèi)容,個別內(nèi)容沒有羅列可以從原書中獲取。)感謝大家的支持!
預(yù)告:下周(2019-2.18 —— 2.22)更新“PHP面試常考內(nèi)容之Memcache和Redis緩存的”專題,敬請期待。
以上內(nèi)容摘自《PHP程序員面試筆試真題解析》書籍,該書已在天貓、京東、當(dāng)當(dāng)?shù)入娚唐脚_銷售。
?
更多PHP相關(guān)的面試知識、考題可以關(guān)注公眾號獲取:琉憶編程庫
?
對本文有什么問題或建議都可以進行留言,將不斷完善追求極致,感謝你們的支持。
轉(zhuǎn)載于:https://www.cnblogs.com/leoyi330/p/10381974.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的PHP面试常考内容之面向对象(3)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Leetcode 583.两个字符串的删
- 下一篇: 遍历文件夹
