php面向对象

php 面向对象

面向对象?

面向对象的好处?

1、学习面向对象可以让你的代码更加的紧凑

2、可以让代码更加优美

3、让更复杂的功能,使用更简单

思维层面

OOA 面向对象分析(了解)

OOD 面向对象设计(了解)

OOP 面向对象编程(重要)

面向对象三大特征

1、封装

2、继承

3、多态

学习面向对象的必须要懂得

1、类

2、对象

对象是类的实例,类是对象的模板

基础

声明类

1
2
3
4
class ClassName
{

}

声明对象

1
$obj = new ClassName();

类的命名规范

1、类名首字母大写

2、遵循大驼峰命名法

3、类名不能使用系统关键字,函数名

4、不能以数字开头,不能使用特殊符号

5、数字可以加在中间或结尾

6、可以使用下划线

7、名字要有意义

成员属性

1、必须使用访问修饰符修饰

2、其他和声明变量相同

成员方法

1、必须使用访问修饰符修饰

2、其他和声明函数相同

访问修饰符

公共的 public

受保护的 protected

私有的 private

类调用

1、类的外部调用属性

1
ClassName->attrName;

2、类的外部调用方法

1
ClassName->methodName();

3、类的内部调用属性

1
$this->attrName;

4、类的内部调用方法

1
$this->methodName();

注:
-> 后面的 name 不用加 $

访问成员属性的值

类的内部

1
$this->attrName;

类的外部

1
$obj->attrName;

修改成员属性的值

类的内部

1
$this->attrName = value;

类的外部

1
$obj->attrName = value;

销毁成员属性的值

1
unset($obj->attrName);

添加成员属性的值

类的内部

1
$this->attrName = value;

类的外部

1
$obj->attrName = value;

注:一般不会用这种方法

魔术方法

__construct 构造方法

1
2
3
4
public function __construct()
{

}

触发时机

实例化这个类时自动触发

参数

可有可无

如果定义了形参,并且没有初始值,那么在实例化对象时时必须传值

作用

批量初始化成员属性时调用

__destruct 析构方法

public function __destruct()
{

}

触发时机

销毁一个对象或者程序结束时自动触发

参数

没有任何参数

作用

垃圾回收

数据库关闭

__get 方法

1
2
3
4
public function __get($arg)
{

}

触发时机

访问非公共属性时自动触发

参数

必须有一个参数

这个参数的值为成员属性的名字

__set 方法

1
2
3
4
public function __set($name, $value)
{

}

触发时机

修改非公共属性时自动触发

参数

必须有两个参数

第一个:非公共成员属性的名字

第二个:外部赋的值

__isset 方法

1
2
3
4
public function __isset($arg)
{

}

触发时机

在类外部用isset函数判断非公共成员属性时自动触发

参数

必须有一个参数

判断的成员属性名

__unset 方法

1
2
3
4
public function __unset($arg)
{

}

触发时机

在类外部用unset函数销毁一个非公共成员属性时自动触发

参数

必须有一个参数

被销毁的成员属性名

__call方法

1
2
3
4
public function __call($funcName, $argsArr)
{

}

触发时机

当外部调用一个不存在的成员方法的时候自动触发

参数

必须有两个参数

第一个:方法名字

第二个:传入的实参 并且以数组方式进行返回

用途

适用于连贯操作的时候

__callStatic方法

1
2
3
4
public function __callStatic($funcName, $argsArr)
{

}

触发时机

外部访问一个不存在的静态的成员方法的时候自动触发

参数

必须要有两个参数

第一个:外部不存在的静态成员方法名

第二个:传入的实参 并以数组的形式返回

__sleep方法

1
2
3
4
public function __sleep()
{
return ['name1', 'name2', 'name3'];
}

触发时机

serialize()序列化的时候自动触发

返回值

返回数组形式,装入想要返回的属性名

__wakeup方法

1
2
3
4
public function __wakeup()
{

}

触发时机

unserialize()反序列化的时候自动触发

__autoload方法

1
2
3
4
function __autoload($arg)
{

}

触发时机

类外部实例化或者继承了一个不存在的类时自动触发

参数

必须有一个参数,这个参数是不存在的类名

注意

这个方法是写在类的外部的

spl_autoload_register方法

1
2
3
4
5
6
spl_autoload_register('test')

function test($className)
{
var_dump($className);
}

触发时机

类外部实例化或者继承了一个不存在的类时自动触发

参数

必须有一个参数,这个参数是一个自定义的函数名

注意

test就是方法名里面可以传入一个形参

形参代表的是实例化或者继承的时候不存在的类名

这个方法是写在类的外部的


__invoke方法

1
2
3
4
public function __invoke()
{

}

触发时机

以函数的方式使用对象 $obj() 的时候自动触发

参数

可有可无,根据实参决定

__clone方法

1
2
3
4
public function __clone()
{

}

触发时机

外部用clone()这个函数的时候自动触发

参数

不能有参数

__toString方法

1
2
3
4
public function __toString()
{
return '';
}

触发时机

对象当字符串使用的时候自动触发

返回值

必须有字符串类型的返回值

__debugInfo方法

1
2
3
4
public function __debugInfo()
{

}

触发时机

在外部 var_dump() 一个对象的时候自动触发

继承

php是单继承,多继承需要使用 trait 关键字

关键字

1
extends

声明一个带有继承的类

1
2
3
4
class childName extends parentName
{

}

child 被称为子类或者派生类

parent 被称为父类或者基类

321关系

public

1、类的外部可以访问

2、子类可以访问

3、内部可以访问

protected

1、类的外部不可以访问

2、子类可以访问

3、内部可以访问

private

1、类的外部不可以访问

2、子类不可以访问

3、内部可以访问

可知

public > protected > private

注意:

在继承的时候子类的关键字的等级 必须要大于或者等于父类的等级

方法重载

当子类的方法名和父类的方法名相同时,子类的方法体会覆盖掉父类的方法体

子类的方法想要使用父类的同名方法时

1
2
3
parentName::method()

parent::method()

推荐使用第二个方式,因为无需知道父类的类名

注意:

如果父类的方法有参数,也需要对应的传过去

静态成员

关键字:static

1
2
3
4
5
6
7
class ClassName
{
public static $attr;
public static function method(){

}
}

调用

不需要实例化对象

在类的内部

1
2
3
self::staticAttr;

self::staticMethod();

在类的外部

1
2
3
ClassName::staticAttr;

ClassName::staticMethod();

通过这种方式调用

final

1
2
3
4
5
6
7
final public ClassName
{
final public function funcName()
{

}
}

1、final修饰的类称为最终类,不能被继承

2、final修饰的方法称为最终方法,不能被重载

常量

关键字:const

定义

1
const ABC = 'abc';

调用

1
2
3
4
5
6
parent::ABC;
$this::ABC;
self::ABC;
parentClassName::ABC;
childClassName::ABC;
$obj::ABC;

对象遍历

外部遍历

1
2
3
foreach ($obj as $key => $value) {
echo $key.'---'.$value.'<br />';
}

内部遍历

1
2
3
foreach ($this as $key => $value) {
echo $key .'---' . $value.'<br />';
}

匿名类

1
2
3
$var = new class{
public $name;
}

$var就是实例化的对象

注:php7支持

抽象类

关键字:Abstract

1
2
3
4
5
6
7
8
9
10
11
12
Abstract class ClassName
{
Abstract public function method($arg);
}

class ChildClassName extends ClassName
{
public function method($arg)
{

}
}

1、Abstract定义的类为抽象类

2、Abstract定义的没有方法体的方法为抽象方法

3、里面可以有抽象方法 可以有普通方法

4、抽象方法如果有形参在继承时必须也有

5、抽象类不能直接实例化如果想使用只能通过继承实现

6、抽象类里面如果有抽象方法,在用子类继承时必须实现

7、Abstract不能修饰带有方法体的方法

接口

定义关键字:interface

实现关键字:implements

1
2
3
4
5
6
7
8
9
10
11
12
interface ClassName
{
Abstract public function method($arg);
}

class ChildClassName implements ClassName
{
public function method($arg)
{

}
}

1、关键字interface定义

2、接口不能被继承,只能用关键字implements实现接口

3、接口可以继承接口

4、接口里面不能带有方法体的方法

5、不能直接实例化如果想使用只能通过类去实现

6、修饰词必须使用public

7、接口不能重复继承

8、怎么继承一个类并且实现多个接口

1
class ChildClassName extends ClassName implements interface1 , interface2

命名空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace namespace1;
class Php
{

}

namespace namespace2;
class Php
{

}

use \namespace1 as ns1;
use \namespace2 as ns2;

$p1 = new \ns1\Php();
$p2 = new \ns2\Php();

作用:解决重名问题

定义:namespace

1、命名空间前面不准许有任何的代码

2、起别名的时候用as

3、使用的时候用use建议加上\

模拟多继承

关键字:trait

1
2
3
4
5
6
7
8
9
trait TraitName
{
public $name;
}

class ClassName
{
use TraitName;
}

1.关键字trait定义

2、不能直接实例化

3、trait可以嵌套trait(一般不这么做)

注意:

解决多个trait 里面方法名重名的问题

1
2
3
4
5
6
7
8
class ClassName
{
use trait1 , trait2;

trait1::method insteadof trait2;
trait1::method as trait1Method;
trait2::method as trait2Method;
}