PHP基础(二):面向对象
面向对象和面向过程有什么区别?
主要有以下不同:
- 出发点不同
- 层次逻辑关系不同
- 数据处理方式与控制程序方式不同
- 分析设计与编码转换方式不同
面向对象的特征是什么?
抽象
封装
封装是指将客观事物抽象成类,每个类对自身的数据和方法实行保护。类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的类或者对象进行隐藏。
继承
继承是一种联结类的层次结构,并且允许和鼓励类的重用,它提供了一种表述共性的方法。子类可以从父类那里继承方法和成员变量,且子类可以修改和增加新的方法使之更适合特殊的需要。
多态
是指相同的调用语句具有不同的表现形式。
面向对象的开发方式有什么优点?
列举以下三个:
- 较高的开发效率(灵活性)
- 保证软件的鲁棒性(重用性)
鲁棒是Robust
的音译,就是 健壮和强壮 的意思,它也是在异常和危险的情况下系统生存的能力。
- 保证软件的高可维护性(扩展性)
类与对象的区别是什么?
对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,一个对象由一组属性和对这组属性进行操作的一组服务组成。
类是具有相同属性和服务的一组对象的集合。
类和对象的关系就如同模具和铸件的关系,类的实例化就是对象,这一类对象的抽象就是类。
PHP5中的魔术方法有哪些?
__get
、__set
、__isset
、__unset
a. 在访问类属性的时候,若属性不可以被访问,则调用__get
函数。
public mixed __get(string $name)
b. 在设置一个对象的属性时,若不可以被访问,则调用__set
函数。
public mixed __set(string $name, mixed $value)
c. 当对不可访问的属性调用isset()
或empty()
时,__isset()
会被调用。
public bool __isset(string $name)
d. 当对不可访问的属性调用unset()
时,__unset()
会被调用。
public bool __unset(string $name)
不可访问包括:
- 属性没有定义
- 属性没有访问权限(属性的访问控制为
protected
或private
)
__construct
、__destruct
a. __construct
是构造方法,实例化对象时调用
b. __destruct
是析构方法,当对象被销毁时调用,一般把需要释放资源的操作放在析构方法中
__call
、__callstatic
a. __call($method, $arg_array)
:当调用一个不可访问的方法时调用
b. __callstatic($method, $arg_array)
:当调用一个不可访问的静态方法时调用
__sleep
、__wakeup
a. __sleep
:序列化(serialize
)的时候调用
b. __wakeup
:反序列化(unserialize
)的时候调用
__toString
打印一个对象时调用
__invoke
可以把对象名当做方法直接调用,它会间接调用这个方法
__set_state
调用var_export
时被调用,用__set_state
的返回值作为var_export
的返回值
__clone
在对象克隆的时候调用。PHP
提供的clone
方法对一个对象实例进行浅拷贝,即对对象内的基本数据类型通过值传递完成拷贝,当对象内部有成员变量时,最好重写__clone()
方法来实现对这个对象变量的深拷贝
__autoload
当实例化一个对象时,若对应的类不存在,则该方法被调用
引申:PHP的魔术常量有哪些?
__LINE__
:返回文件中当前的行号__FILE__
:返回当前文件的完整路径__FUNCTION__
:返回所在的函数名__CLASS__
:返回所在的类名__METHOD__
:返回所在的类方法名__DIR__
:返回当前文件所在的目录__NAMESPACE__
:返回当前命名空间的名称(区分大小写)__TRAIT__
:返回trait
被定义时的名字
值传递和引用传递的区别
值传递:
在方法调用中,实参会把它的值传递给形参,形参只是用实参的值初始化一个临时的存储单元,因此形参和实参虽然有相同的值,但是却有不同的存储单元,此时对形参的改变不会影响实参的值。
引用传递:
在方法调用中,传递的是对象的引用(对象的地址),这时形参和实参的对象指向的是同一块存储单元,因此对形参的修改就会影响实参的值。
注意:基本的数据类型默认使用值传递,对象会使用引用传递
什么是对象克隆?
对于对象而言,PHP
用的是引用传递,也就是说,对象间的赋值操作只是赋值了一个引用的值,而不是整个对象的内容。通过clone
关键字克隆出来的对象只是对象的一个浅拷贝,当对象中没有引用变量的时候这种方法是可以正常工作的,但是当对象中也存在引用变量的时候,这种拷贝方式就会有问题。为了使两个对象完全独立,需要对对象进行深拷贝,PHP提供了__clone
魔术方法(类似于C++
的拷贝构造函数),把需要深拷贝的属性,在这个方法中进行拷贝。
什么是延迟静态绑定?
PHP
延迟静态绑定技术允许父类可以使用子类重载的静态方法。
self
和static
的区别:
self
就是写在哪个类里面, 实际调用的就是哪个类.static
代表使用的这个类, 就是你在父类里写的static
,然后被子类覆盖,使用的就是子类的方法或属性.self
引用的是当前类;static
允许函数在运行时绑定调用类。
作用域范围有哪几种?
public
(共有的)、protected
(受保护的)、private
(私有的)
什么是继承?
主要有以下几个特性:
PHP
语言不支持多继承,即子类只能有一个父类,但是可以通过实现多个接口来达到多继承的目的子类只能继承父类的非私有成员变量和方法
当子类中的成员变量和父类中定义的成员变量同名时,子类中的成员变量会覆盖父类中的成员变量
当子类中的方法和父类中的方法有相同的方法签名(相同的方法名,相同的参数个数和类型)时,子类将会覆盖父类的方法,而不是重载
PHP
提供了final
关键字,当在方法前使用此关键字时,表明此方法不能被子类覆盖,被final
关键字修饰的类,禁止被其他类继承
抽象类与接口有什么区别和联系?
抽象类:
PHP5
支持抽象类和抽象方法。被定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方法和参数,不能定义其具体的功能实现。
接口:
可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。在这种情况下,可以通过interface
关键字来定义一个接口,在接口中声明的方法都不能有方法体。
主要有以下区别:
对接口的实现是通过关键字
implements
来实现的,而抽象类继承则是使用类继承的关键字extends
实现的接口没有数据成员(可以有常量),但是抽象类有数据成员(各种类型的成员变量),抽象类可以实现数据的封装
接口没有构造函数,抽象类可以有构造函数
接口中的方法都是
public
类型,而抽象类中的方法可以使用private
,protected
或public
来修饰一个类可以同时实现多个接口,但是只能继承一个抽象类
什么是多态?
相同的调用语句具有不同的表现形式。