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 相关文章推荐
Uchome1.2 1.5 代码学习 common.php
Apr 24 PHP
PHP随机字符串生成代码(包括大小写字母)
Jun 24 PHP
跟我学Laravel之请求与输入
Oct 15 PHP
php实现两表合并成新表并且有序排列的方法
Dec 05 PHP
经典PHP加密解密函数Authcode()修复版代码
Apr 05 PHP
php生成年月日下载列表的方法
Apr 24 PHP
php中动态变量用法实例
Jun 10 PHP
浅谈PHP中output_buffering
Jul 13 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
Mar 05 PHP
降低PHP Redis内存占用
Mar 23 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
Oct 20 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数组中头部和尾部添加元素的方法(array_unshift,array_push)
2017/04/10 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
在php的yii2框架中整合hbase库的方法
2018/09/20 PHP
PHP实现字符串的全排列详解
2019/04/24 PHP
基于JQuery框架的AJAX实例代码
2009/11/03 Javascript
jQuery实现点击标题输入详细信息
2013/04/16 Javascript
火狐textarea输入法的bug的触发及解决
2013/07/24 Javascript
javascript 数字格式化输出的实现代码
2013/12/10 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
初识Node.js
2014/09/03 Javascript
使用Chrome调试JavaScript的断点设置和调试技巧
2014/12/16 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
Javascript aop(面向切面编程)之around(环绕)分析
2015/05/01 Javascript
在AngularJS中如何使用谷歌地图把当前位置显示出来
2016/01/25 Javascript
数据结构中的各种排序方法小结(JS实现)
2016/07/23 Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
python 判断自定义对象类型
2009/03/21 Python
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
python判断字符串是否包含子字符串的方法
2015/03/24 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
2017/12/18 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
2018/03/31 Python
Python OpenCV对本地视频文件进行分帧保存的实例
2019/01/08 Python
Python 获取 datax 执行结果保存到数据库的方法
2019/07/11 Python
详解Django定时任务模块设计与实践
2019/07/24 Python
python flask web服务实现更换默认端口和IP的方法
2019/07/26 Python
PyTorch的自适应池化Adaptive Pooling实例
2020/01/03 Python
python实现引用其他路径包里面的模块
2020/03/09 Python
解决jupyter运行pyqt代码内核重启的问题
2020/04/16 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
个人自我鉴定范文
2013/10/04 职场文书
田径运动会开幕式及主持词
2014/03/28 职场文书
责任书范本
2014/08/25 职场文书
2014年群众路线教育实践活动整改措施
2014/09/24 职场文书
《颐和园》教学反思
2016/02/19 职场文书
Windows Server 2012 修改远程默认端口3389的方法
2022/04/28 Servers
python数据处理之Pandas类型转换
2022/04/28 Python