1.4 面向对象摘要
面向对象包括3部分内容:OOA、OOD、OOP。面向对象编程的两个重要概念是类和对象。

面向对象编程的三大特点

封装、继承、多态。
封装性
封装性,也可以称为信息隐藏。就是将一个类的使用和实现分开,只保留有限的接口(方法)与外部联系。这样对于用到该类的开发人员,只要知道这个类如何使用即可,而不用去关心这个类是如何实现的。
    public
    private
    protected
继承性
继承性就是派生类(子类)自动继承一个或多个基类(父类)中的属性与方法,并可以重写或添加新的属性或方法。继承这个特性简化了对象和类的创建,提高了代码的可重用性。继承分单继承和多继承,PHP 所支持的是单继承,也就是说,一个子类有且只有一个父类。
继承简化了对象、类的创建,增加了代码的可重用性。但PHP只支持单继承。如果想实现多重继承,就要使用接口或者 Trait。
接口实例:
1
<?php
2
interface a
3
{
4
public function foo();
5
}
6
7
interface b
8
{
9
public function bar();
10
}
11
12
interface c extends a, b
13
{
14
public function baz();
15
}
16
17
class d implements c
18
{
19
public function foo()
20
{
21
}
22
23
public function bar()
24
{
25
}
26
27
public function baz()
28
{
29
}
30
}
31
?>
Copied!
Trait 实例
1
<?php
2
trait ezcReflectionReturnInfo {
3
function getReturnType() { /*1*/ }
4
function getReturnDescription() { /*2*/ }
5
}
6
7
class ezcReflectionMethod extends ReflectionMethod {
8
use ezcReflectionReturnInfo;
9
/* ... */
10
}
11
12
class ezcReflectionFunction extends ReflectionFunction {
13
use ezcReflectionReturnInfo;
14
/* ... */
15
}
16
?>
Copied!
注意:从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。
多态性
先简单说一下多态,多态的三大特征:
    子类继承父类
    子类重写父类
    父类指向子类
多态实现的前提:必须是类与类之间要有关系,要么继承,要么实现,存在重写(override),其实就是抽象函数或接口。
多态的应用:父类对象的引用指向子类对象,其实本质上就是一个向上转型。
多态的好处:大大提高程序的扩展,增强系统的灵活性,降低模块间的耦合。 具体Java代码实现如下:
1
abstract class Employee{
2
abstract void continueToWork();
3
}
4
class Sales extends Employee{
5
private void makeSalePlan(){
6
System.out.println("make sale plan");
7
}
8
9
public void continueToWork(){
10
makeSalePlan();
11
}
12
}
13
14
class Market extends Employee{
15
private void makeProductPrice(){
16
System.out.println("make product price");
17
}
18
19
public void continueToWork(){
20
makeProductPrice();
21
}
22
}
23
24
class Engineer extends Employee{
25
private void makeNewProduct(){
26
System.out.println("make new product");
27
}
28
29
public void continueToWork(){
30
makeNewProduct();
31
}
32
}
Copied!
错误的调用示范:
1
class Demo{
2
public static void main(String[] args){
3
Sales s = new Sales();
4
s.continueToWork();
5
Market m = new Market();
6
m.continueToWork();
7
Engineer e = new Engineer();
8
e.continueToWork();
9
}
10
}
Copied!
以上的这种调用并不能称为多态,虽然看起来都通过调用continueToWork()来得到结果,但是并不是通过同一接口来实现的,这只是不同类的对象都有相同名称的接口方法。
正确的调用方式:
1
class Demo{
2
public static void main(String[] args){
3
Work(new Sales());//Employee e = new Sales();
4
Work(new Market());//Employee e = new Market();
5
Work(new Engineer());//Employee e = new Engineer();
6
}
7
public static void Work(Employee e){
8
e.continueToWork();
9
}
10
}
Copied!
上面通过调用统一的接口Work()来工作,这种调用才是多态。
还可以利用重载来实现伪多态。
1
class Demo{
2
public static void main(String[] args){
3
Work(new Sales());
4
Work(new Market());
5
Work(new Engineer());
6
}
7
public static void Work(Sales s){
8
s.continueToWork();
9
}
10
public static void Work(Market m){
11
m.continueToWork();
12
}
13
public static void Work(Engineer e){
14
e.continueToWork();
15
}
16
}
Copied!
为什么我称上面调用是伪多态呢?因为上述的这种方式,细究其实跟第一种错误调用方式是一样的,只不过利用了重载加以封装,使得看起来是通过统一的接口Work()来工作,但其实它并没有让父类对象的引用指向子类对象。
php代码实现多态:
1
<?php
2
abstract class Employee{
3
abstract function continueToWork();
4
}
5
class Sales extends Employee{
6
private function makeSalePlan(){
7
echo "make sale plan";
8
}
9
10
public function continueToWork(){
11
$this->makeSalePlan();
12
}
13
}
14
15
class Market extends Employee{
16
private function makeProductPrice(){
17
echo "make product price";
18
}
19
20
public function continueToWork(){
21
$this->makeProductPrice();
22
}
23
}
24
25
class Engineer extends Employee{
26
private function makeNewProduct(){
27
echo "make new product";
28
}
29
30
public function continueToWork(){
31
$this->makeNewProduct();
32
}
33
}
34
35
class Demo{
36
public function Work(Employee $employeeObj){//添加父类类型限制传参类型,使其满足多态第三点要求,父类指向子类
37
$employeeObj->continueToWork();
38
}
39
}
40
//调用
41
$obj = new Demo();
42
$obj->Work(new Sales());
43
$obj->Work(new Market());
44
$obj->Work(new Engineer());
45
?>
Copied!

其他概念

$this->和"::"的使用
在对类完成实例化之后可以通过对象名+方法名来调用方法“对象名->方法名”。但在定义类时,根本无法得知对象名称是什么,这时如果想调用本类中的方法,就要用伪变量this->方法名,所以this值可以在类的内部使用。
相比伪变量$this只能在类的内部使用,操作符“::”更为强大。操作符"::"可以在没有声明任何实例的情况下访问类中的成员方法和成员变量。
1
关键字::变量名/常量名/方法名
Copied!
    parent:可以调用父类中的成员变量、成员方法和常量
    self:可以调用当前类中的静态成员和常量
    类名:可以调用本类中的变量、常量和方法
静态变量(方法)
1
关键字::静态成员
Copied!
    self:在类内部调用静态成员时所使用。
    静态成员所在的类名,在类外调用类内部的静态成员时所使用。
对象比较
在实际开发中可能需要判断两个对象之间的关系时克隆还是引用,这时可以使用比较运算符“==”和“===”。两个等号“==”是比较两个对象的内容,3个等号“===”是比较对象的引用地址。
对象类型检测
instanceof 操作符可以检测当前对象是属于哪个类。
1
ObjectName instanceof ClassName
Copied!
PHP 加密函数
Last modified 1yr ago