**对象是类的实例化结果。类是对象的抽象描述。**
类的定义:
[修饰符] class 类名 [extends 父类] [implements 接口1[,接口2...]]{
【成员属性】定义变量
【成员方法】定义函数
}
**类前的修饰符:final、abstract**
**常用属性的修饰符:public、protected、private、static**
**常用的修饰符:public、protected、private、static、abstract、final**
*****
我们在类中调用自己的成员属性或函数都是使用 $this->调用。
*****
构造方法:__construct(),实例化一个对象第一个自动执行的方法。
析构方法:__destruct();对象被销毁时最后自动调用的方法.
*****
__get($name):直接输出对象中的非公有属性时会自动调用。
```
public function __get($par){
return $this->$par
}
```
*****
__set($name,$val):直接设置对象中的非公有属性会自动调用。
```
public function __set($par,$value){
$this->$par=$value;
}
```
(如果变量没有在类的内部定义,会添加)
当对未定义的变量调用isset() 或 empty()时,__isset() 会被调用。
非公有对外界都是不可见的,用isset可以判断存不存在.
当对未定义的变量调用unset()时,__unset() 会被调用。
```
__unset function __unset($par){
unset($this->$par)
}
```
*****
## 继承:extends
**继承:extends,子类会继承父类的公有,受保护方法。如果子类方法和父类重名则覆盖。**
1.php只支持单继承。一个子类只能有一个父类。但一个类可以被多个类继承。
2.子类继承父类所有属性,但私有属性不能直接访问,子类可以通过继承父类的方法来间接访问父类的私有属性。
3.通过2可推出子类继承的方法是引用而不是复制。
4.子类中新增加的属性和方法叫扩展。子类中与父类同名的属性是对父类的覆盖。
5.如果子类的属性为私有则无法继承父类的set/get
*****
## parent::
1调用父类被覆盖的方法
2子类在继承父类后,子类的构造方法中要先继承父类的构造方法
```
public function __construct($name,$age,$classid){
//先构造父类
parent::_\construct($name,$age);
$this->classid = $classid;
}
```
3覆盖父类的方法(升级)
```
public function getinfo(){
return parent::getinfo().":".$this->classid;
}
```
*****
## final修饰符(禁止方法被覆盖,类被继承)
1.静态方法(属性)调用之前不用实例化类可以直接使用。
类::静态属性 类::静态方法
2.在类中,不能使用$this来引用静态变量,而要用self(自己)来引用。
self::$静态属性 self::静态方法
3.self在静态方法中可以调用其他静态方法和属性,静态中不可以调用非静态($this)
4.在一个类的方法中若没有$this,默认为静态
实例化后,静态方法可以使用对象调用。静态属性不行。
`const ConstName="value";`
1.只能修饰成员属性
2.类内访问通过self:: ;内外访问 类名::常量名
instanceof 检测当前对象实例是否属于某一个类的类型
*****
## 单例:
创建类A:
私有化静态变量默认为空,(用来存放实例化)。
私有化构造方法。
公有静态方法:
判断私有化静态变量是否为空
为空则实例化本类赋值给私有化静态变量
返回私有化静态变量。
其他方法。。
使用:
$a=类名::公有静态方法。
$b=类名::公有静态方法。
```
class A{
private static $ob=null;
//私有化构造方法
private function __construct(){
}
public static function makeA(){
if(empty(self::$ob)){
self::$ob = new A();
}
return self::$ob;
}
//编写其他实用方法
public function add(){
}
public function del(){
}
}
$a1 = A::makeA();
$a2 = A::makeA();
var_dump($a1);
var_dump($a2);
```
*****
## 数组的串行化
(json_encode/json_decode)
$s = json_encode($a); //将数组复合类型转成json格式
$b = json_decode($s,true); //将json格式转回数组格式
## 对象的串行化
```
serialize()//串行
unserialize()//反串行
$str = serialize($s);
file_put_contents("ob.txt",$str);
$ob = unserialize($str);
```
__sleep(): 是执行串行化时自动调用的方法,目的是实现资源类型的属性实关闭操作。
(sleep方法需要返回一个数组,其中数组中的值是串行化时要保留的属性名)
```
public function __sleep(){
//关闭资源
if($this->link){
fclose($this->link);
$this->link=null;
}
return array("fname"); //并返回串行时需要保留的属性名
}
```
__wakeup():是在执行反串行化时自动调用的方法,目的是实现资源属性的打开(sleep方法关闭的资源)
```
public function __wakeup(){
$this->link = fopen($this->fname,"a+");
}
```
## 对象克隆clone
由于对象属于引用赋值,所以 =不能用来复制。=相当于起别名。
$a2 = clone $a1;
__toString()直接输出一个对象时,会自动调用。
__call($name,$arrays)当调用一个不可访问的方法(未定义或不可见),自动调用
__autoload(类名)
当实例化一个对象时,这个类不存在,则自动调用此函数,并将类名存入参数。
```
function __autoload($classname){
$filename = strtolower($classname).".class.php";
if(file_exists("./action/".$filename)){
require("./action/".$filename);
}elseif(file_exists("./model/".$filename)){
require("./model/".$filename);
}else{
die("找不到{$classname}类!");
}
}
```
*****
php的类型约束:目前只支持array和对象(类、抽象类、接口);
*****
## 抽象类:abstract
**当类中有一个方法,他没有方法体,直接分号结束。**
`public abstract function fun();`
**抽象方法。必须使用abstract定义。包含这种方法的类必须是抽象类。**
abstract class A
抽象类的特点:
不能实例化,也就new成对象
若想使用抽象类,就必须定义一个类去继承这个抽象类,并定义覆盖父类的抽象方法(实现抽象方法)。
*****
**含有抽象方法的类肯定是抽象类,但是不是所有的抽象类都必须包含抽象方法。**
*****
```
abstract class A{
public function fun1(){
echo "class A method fun1...";
}
public abstract function fun2($a);
}
class B extends A{
public function fun2($c){
echo "class B method fun2...";
}
}
class Test{
public function demo(A $a){
$a->fun2(10);
}
}
$b = new B();
$b->fun1();
$b->fun2(10);
$t = new Test();
$t->demo(new B());
```
## 接口:interface
**接口:interface,假如一个抽象类中所有的方法都是抽象的,那么可以使用另外一种方式定义:接口。**
**接口中只能有常量与抽象方法。**
```
interface 接口名{
[常量定义]
[抽象方法定义] //注意不要有abstract关键字
}
实现方式:class 类名 implements 接口名,接口名2{
实现体。。
}
```
*****
//接口的定义
```
//定义一个接口A,内有两个方法(抽象方法)
interface A{
const PI=3.14; //在接口中可以定义常量和抽象方法
public function fun1();
public function fun2($a);
}
//定义一个类B去实现一个接口A
abstract class B implements A{
public function fun1(){
echo "class B method fun1...";
}
}
class C extends B{
public function fun2($c){
echo "class C method fun2...";
}
}
$c = new C();
$c->fun1();
$c->fun2(10);
```
## 多态:
**对于同一个方法,传入不同的对象,实现不同的效果。**
**同一个操作作用于不同的类的实例,将产生不同的执行结果。**
思路:
定义接口/抽象类
存放抽象方法
定义类
定义方法 类型约束必须为上面定义的对象。
实现对象的抽象方法。
类1继承接口/抽象类
重写抽象方法。
类2继承接口/抽象类
重写抽象方法。
*****
实现:
//模拟多态的使用(接口版)
```
//主板的驱动程序
class mainboard{
public function running(PCI $pci){
$pci->start();
}
}
//========主板厂商========
//主板上的pci插槽规范接口
interface PCI{
public function start(); //启动
}
//======声卡厂家=====================
class soundcard implements PCI{
public function start(){//启动
echo "声卡启动...";
}
}
//======网卡厂家=====================
class networkcard implements PCI{
public function start(){//启动
echo "网卡启动...";
}
}
//系统程序
$md = new mainBoard(); //主板程序
$sd = new soundcard(); //声卡
$nc = new networkcard();//网卡
$md->running($sd); //声卡接入主板程序使用
$md->running($nc); //网卡接入主板程序使用
```
\======================================
```
interface employee{
public function working();
}
class teacher impements employee{
public function working(){
echo '1';
}
}
class coder implements employee{
public function working(){
echo '2';
}
}
function doprint(employee $obj){
$obj->working();
}
$a=new teacher;
$b=new coder;
doprint($a);
doprint($b);
```
## 异常处理
```
//异常处理的使用
//除法函数
function demo($a,$b){
if($b==0){
//当除数为0时,自定义的抛出一个异常错误对象。
throw new Exception("除数不可以为零!",110);
}
return $a/$b;
}
echo "start.....";
//异常处理
try{ //捕获异常
//调用
echo "1aaaaaaaaa";
echo "2aaaaaaaaa";
echo demo(100,0);
echo "3aaaaaaaaa";
echo "4aaaaaaaaa";
}catch(Exception $e){ //异常处理
echo "计算错误,原因:".$e->getMessage();
echo $e->getCode().":".$e->getFile().":".$e->getLine();
}
echo "...end..";
```
- 消息队列
- 为什么要用消息队列
- 各种消息队列产品的对比
- 消息队列的优缺点
- 如何保证消息队列的高可用
- 如何保证消息不丢失
- 如何保证消息不会重复消费?如何保证消息的幂等性?
- 如何保证消息消费的顺序性?
- 基于MQ的分布式事务实现
- Beanstalk
- PHP
- 函数
- 基础
- 基础函数题
- OOP思想及原则
- MVC生命周期
- PHP7.X新特性
- PHP8新特性
- PHP垃圾回收机制
- php-fpm相关
- 高级
- 设计模式
- 排序算法
- 正则
- OOP代码基础
- PHP运行原理
- zavl
- 网络协议new
- 一面
- TCP和UDP
- 常见状态码和代表的意义以及解决方式
- 网络分层和各层有啥协议
- TCP
- http
- 二面
- TCP2
- DNS
- Mysql
- 锁
- 索引
- 事务
- 高可用?高并发?集群?
- 其他
- 主从复制
- 主从复制数据延迟
- SQL的语⾔分类
- mysqlQuestions
- Redis
- redis-question
- redis为什么那么快
- redis的优缺点
- redis的数据类型和使用场景
- redis的数据持久化
- 过期策略和淘汰机制
- 缓存穿透、缓存击穿、缓存雪崩
- redis的事务
- redis的主从复制
- redis集群架构的理解
- redis的事件模型
- redis的数据类型、编码、数据结构
- Redis连接时的connect与pconnect的区别是什么?
- redis的分布式锁
- 缓存一致性问题
- redis变慢的原因
- 集群情况下,节点较少时数据分布不均匀怎么办?
- redis 和 memcached 的区别?
- 基本算法
- MysqlNew
- 索引new
- 事务new
- 锁new
- 日志new
- 主从复制new
- 树结构
- mysql其他问题
- 删除
- 主从配置
- 五种IO模型
- Kafka
- Nginx
- trait
- genergtor 生成器
- 如何实现手机扫码登录功能
- laravel框架的生命周期