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相关的面试知识、考题能够关注公众号获取:琉忆编程库
图片描述

对本文有什么问题或建议均可以进行留言,将不断完善追求极致,感谢大家的支持。

相关文章
相关标签/搜索