php面试中关于面向对象的相关问题


Posted in PHP onFebruary 13, 2019

PHP中面向对象常考的知识点有以下7点,我将会从以下几点进行详细介绍说明,帮助你更好的应对PHP面试常考的面向对象相关的知识点和考题。

整个面向对象文章的结构涉及的内容模块有:

  • 一、面向对象与面向过程有什么区别?
  • 二、面向对象有什么特征?
  • 三、什么是构造函数和析构函数?
  • 四、面向对象的作用域范围有哪几种?
  • 五、PHP 中魔术方法有哪些?
  • 六、什么是对象克隆?
  • 七、this、self和parent的区别是什么?
  • 八、抽象类与接口有什么区别与联系?
  • 九、PHP面向对象的常考面试题讲解

关于PHP面向对象的内容将会被分为三篇文章进行讲解完整块内容,第一篇主要讲解一到四点内容,第二篇主要讲解五到八的内容,第三篇围绕第九点进行讲解。

以下正文的内容都来自《PHP程序员面试笔试宝典》书籍,如果转载请保留出处:

一、面向对象与面向过程有什么区别?

面向对象是当今软件开发方法的主流方法之一,它是把数据及对数据的操作方法放在一起,作为一个相互依存的整体,即对象。对同类对象抽象出其共性,即类,类中的大多数数据,只能被本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。例如,站在抽象的角度,人类具有身高、体重、年龄、血型等一些特称,人类会劳动、会直立行走、会吃饭、会用自己的头脑去创造工具等这些方法,人类仅仅只是一个抽象的概念,它是不存在的实体,但是所有具备人类这个群体的属性与方法的对象都称为人,这个对象人是实际存在的实体,每个人都是人这个群体的一个对象。

而面向过程是一种以事件为中心的开发方法,就是自顶向下顺序执行,逐步求精,其程序结构是按功能划分为若干个基本模块,这些模块形成一个树状结构,各模块之间的关系也比较简单,在功能上相对独立,每一模块内部一般都是由顺序、选择和循环三种基本结构组成,其模块化实现的具体方法是使用子程序,而程序流程在写程序时就已经决定。例如五子棋,面向过程的设计思路就是首先分析问题的步骤:第一步,开始游戏;第二步,黑子先走;第三步,绘制画面;第四步,判断输赢;第五步,轮到白子;第六步,绘制画面;第七步,判断输赢;第八步,返回步骤二;第九步,输出最后结果。把上面每个步骤用分别的函数来实现,就是一个面向过程的开发方法。

具体而言,二者主要有以下几个方面的不同之处。

1)出发点不同。面向对象是用符合常规思维方式来处理客观世界的问题,强调把问题域的要领直接映射到对象及对象之间的接口上。而面向过程方法则不然,它强调的是过程的抽象化与模块化,它是以过程为中心构造或处理客观世界问题的。

2)层次逻辑关系不同。面向对象方法则是用计算机逻辑来模拟客观世界中的物理存在,以对象的集合类作为处理问题的基本单位,尽可能地使计算机世界向客观世界靠拢,以使问题的处理更清晰直接,面向对象方法是用类的层次结构来体现类之间的继承和发展。面向过程方法处理问题的基本单位是能清晰准确地表达过程的模块,用模块的层次结构概括模块或模块间的关系与功能,把客观世界的问题抽象成计算机可以处理的过程。

3)数据处理方式与控制程序方式不同。面向对象方法将数据与对应的代码封装成一个整体,原则上其他对象不能直接修改其数据,即对象的修改只能由自身的成员函数完成,控制程序方式上是通过“事件驱动”来激活和运行程序。而面向过程方法是直接通过程序来处理数据,处理完毕后即可显示处理结果,在控制程序方式上是按照设计调用或返回程序,不能自由导航,各模块之间存在着控制与被控制、调用与被调用。

4)分析设计与编码转换方式不同。面向对象方法贯穿软件生命周期的分析、设计及编码之间是一种平滑过程,从分析到设计再到编码是采用一致性的模型表示,即实现的是一种无缝连接。而面向过程方法强调分析、设计及编码之间按规则进行转换,贯穿软件生命周期的分析、设计及编码之间,实现的是一种有缝的连接。

二、面向对象有什么特征?

面向对象的主要特征有抽象、继承、封装和多态。

1)抽象。抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

2)继承。继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且子类可以修改或增加新的方法使之更适合特殊的需要。

3)封装。封装是指将客观事物抽象成类,每个类对自身的数据和方法实行保护。类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的信息进行隐藏。

4)多态。多态是指允许不同类的对象对同一消息做出响应。多态包括参数化多态和包含多态。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好地解决了应用程序函数同名问题。

三、什么是构造函数和析构函数?

1.构造函数

在PHP5之前的版本,构造函数的名字必须与类的名字相同,而从PHP5开始,开发者可以定义一个名为__construct的方法作为构造函数。构造函数的作用就是当类被实例化的时候会被自动调用,因此构造函数主要用于做一些初始化的工作。使用__construct作为构造函数名字的一个好处是,当类名修改的时候,不需要修改构造函数的名字。它的声明形式为
void __construct ([ mixed $args [, $... ]] )

在C++语言中,子类的构造函数会隐式地调用父类的无参数的构造函数。但是在PHP中,子类的构造函数不会隐式地去调用父类的构造函数,需要开发者通过parent::__construct()来显式地去调用父类的构造函数。当子类没有定义构造函数的时候,它会继承父类的构造函数,但前提是父类的构造函数不能被定义为private。使用示例如下:

<?php  
  class BaseClass {
    function __construct() {
      print "Base constructor\n";
    }
  }
  class SubClass extends BaseClass {
    function __construct() {
      parent::__construct();
      print "Sub constructor\n";
    }
  }
  // 会调用父类构造函数
  $obj = new BaseClass();
  //调用子类构造函数,子类构造函数会去调用父类构造函数
  $obj = new SubClass();
?>

程序的运行结果为

Base constructor
Base constructor
Sub constructor

从上面的讲解中可以发现,从PHP5开始多了一种构造函数定义的方法。为了实现不同版本PHP代码的兼容,在PHP5的类中找不到 __construct() 函数并且也没有从父类继承一个的话,那么它就会尝试寻找旧式的构造函数(与类同名的函数)。这种兼容的方法存在一个风险:在PHP5之前的版本中开发的类中已有一个名为 __construct() 的方法却被用于其他用途时,PHP5的类会认为这是一个构造函数,从而当类实例化时自动执行这个方法。

从 PHP 5.3.3 开始,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。

2.析构函数

析构函数是在PHP5引入的,它的作用与调用时机和构造函数刚好相反,它在对象被销毁时自动执行。析构函数__destruct()结构形式如下:

function __destruct(){
  /* 类的初始化代码*/
}

需要注意的是,析构函数是由系统自动调用的,因此,它不需要参数。

默认情况下,系统仅释放对象属性所占用的内存,并不销毁在对象内部申请的资源(例如,打开文件、创建数据库的连接等),而利用析构函数在使用一个对象之后执行代码来清除这些在对象内部申请的资源(关闭文件、断开与数据库的连接)。
与构造函数类似,如果想在子类中调用父类的析构函数,那么需要显式地调用:parent::__destruct()。如果子类没有定义析构函数,那么它会继承父类的析构函数。

当对象不再被引用时,将调用析构函数。如果要明确地销毁一个对象,那么可以给指向对象的变量不分配任何值,通常将变量赋值为NULL或者用unset()函数。示例代码如下:

<?php 
  class des{
    function __destruct(){
      echo "对象被销毁,执行析构函数<br>";
    }
  }
  $p=new des(); /* 实例化类 */
  echo "程序开始<br>";
  unset($p); /* 销毁变量$p */
  echo "程序结束";
?>

四、面向对象的作用域范围有哪几种?

在PHP5中,类的属性或者方法主要有public、protected和private三种类作用域,它们的区别如下:

1)public(公有类型)表示全局,类内部、外部和子类都可以访问。

默认的访问权限为public,也就是说,如果一个方法没有被public、protected或private修饰,那么它默认的作用域为public。

2)protected(受保护类型)表示受保护的,只有本类或子类可以访问。

在子类中,可以通过self::var或self::method访问,也可以通过parent::method来调用父类中的方法。
在类的实例化对象中,不能通过$obj->var来访问protected类型的方法或属性。

3)private(私有类型)表示私有的,只有本类内部可以使用。

该类型的属性或方法只能在该类中使用,在该类的实例、子类、子类的实例中都不能调用私有类型的属性和方法。

PHP 相关文章推荐
PHP 时间转换Unix时间戳代码
Jan 22 PHP
php 函数中使用static的说明
Jun 01 PHP
PHP实现删除非站内外部链接实例代码
Jun 17 PHP
php字符串替换函数substr_replace()用法实例
Mar 17 PHP
php通过asort()给关联数组按照值排序的方法
Mar 18 PHP
Apache连接PHP后无法启动问题解决思路
Jun 18 PHP
解决nginx不支持thinkphp中pathinfo的问题
Jul 21 PHP
PHP之浮点数计算比较以及取整数不准确的解决办法
Jul 29 PHP
php实现XSS安全过滤的方法
Jul 29 PHP
使用JavaScript创建新样式表和新样式规则
Jun 14 PHP
laravel获取不到session的三种解决办法【推荐】
Sep 16 PHP
php微信小程序解包过程实例详解
Mar 31 PHP
PHP中检查isset()和!empty()函数的必要性
Feb 13 #PHP
PHP实现PDO操作mysql存储过程示例
Feb 13 #PHP
在PHP中输出JS语句以及乱码问题的解决方案
Feb 13 #PHP
PHP实现通过文本文件统计页面访问量功能示例
Feb 13 #PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
Feb 13 #PHP
PHP封装的简单连接MongoDB类示例
Feb 13 #PHP
总结PHP中初始化空数组的最佳方法
Feb 13 #PHP
You might like
php读取msn上的用户信息类
2008/12/05 PHP
PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
2014/09/29 PHP
浅谈PHP接收POST数据方式
2015/06/05 PHP
PHP文件上传之多文件上传的实现思路
2016/01/27 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
2017/09/16 PHP
PHP数组去重的更快实现方式分析
2018/05/09 PHP
js去字符串前后空格5种实现方法及比较
2013/04/03 Javascript
JavaScript中的无阻塞加载性能优化方案
2014/10/10 Javascript
javascript实现youku的视频代码自适应宽度
2015/05/25 Javascript
jQuery实现自定义右键菜单的树状菜单效果
2015/09/02 Javascript
Jquery元素追加和删除的实现方法
2016/05/24 Javascript
JS实现显示带倒影的图片横排居中放大展示特效实例【测试可用】
2016/08/23 Javascript
canvas实现十二星座星空图
2017/02/14 Javascript
xmlplus组件设计系列之树(Tree)(9)
2017/05/02 Javascript
使用javascript函数编写简单银行取钱存钱流程
2018/05/26 Javascript
解决betterScroll在vue中存在图片时,出现拉不动的问题
2018/09/27 Javascript
如何实现小程序tab栏下划线动画效果
2019/05/18 Javascript
JavaScript实现轮播图片完整代码
2020/03/07 Javascript
python实现的简单猜数字游戏
2015/04/04 Python
用python做一个搜索引擎(Pylucene)的实例代码
2017/07/05 Python
使用pyinstaller打包PyQt4程序遇到的问题及解决方法
2019/06/24 Python
python实现视频读取和转化图片
2019/12/10 Python
Python实现AI换脸功能
2020/04/10 Python
python如何调用java类
2020/07/05 Python
HTML5 Canvas标签使用收录
2009/07/07 HTML / CSS
浅谈Html5移动端ios/Android兼容性总结
2018/06/01 HTML / CSS
南京迈特望C/C++面试题
2012/07/09 面试题
什么是GWT的Module
2013/01/20 面试题
上课玩手机的检讨书
2014/10/01 职场文书
2015年人事工作总结范文
2015/04/09 职场文书
秋收起义观后感
2015/06/11 职场文书
安全教育培训心得体会
2016/01/15 职场文书
Angular CLI发布路径的配置项浅析
2021/03/29 Javascript
Python中Permission denied的解决方案
2021/04/02 Python
html+css 实现简易导航栏功能
2021/04/07 HTML / CSS
MySQL读取JSON转换的方式
2022/03/18 MySQL