类与对象

PHP5起完全重写了对象模型。

类的定义

class 类名{
  // 声明属性(可声明常量或变量)
const 常量名 = 值;
public $变量名 = 值; // 声明方法 public function 方法名(){ // 方法体 } }

类名 :不能使用PHP保留字。必须以字母或下划线开头,后跟若干字母、下划线或数字。

 $this 是一个到主叫对象的引用

创建对象(实例)  - 前提:类需提前定义好

在类外部创建

$对象名 = new 类名();

在类内部创建

$对象名 = new self;
$对象名 = new parent;

访问属性与方法

$对象名->属性名;
$对象名->方法名();

类的继承 - 只支持单继承

class 子类名称 extends 父类名称{}

子类会继承父类的公有及受保护属性和方法。

被继承的属性和方法可以通过同样的名称重新声明来覆盖。

覆盖方法时,参数必须保持一致。(构造方法除外)

可以通过parent::来访问被覆盖的属性或方法。

如果父类定义方法时使用了final,则该方法不可覆盖。

 获取类的完全限定名称 - 对使用了命名空间的类很有用

php 5.5起

类名::class

类的属性

// 定义
访问修饰符 $属性名 = 常数; // 访问修饰符:public/protected/private 常数是指PHP在编译阶段就可以得到的值,而不依赖运行时的信息才能求值
// 类方法中的访问方式
$this->属性名;  // 非静态属性
self::$属性名;  // 静态属性

类的常量

// 定义
const 常量名 = 值;
// 类方法中访问
self::常量名;

类的自动加载

php5中,spl_autoload_register()函数可以注册任意数量的自动加载器,当使用尚未被绑定的类或接口时自动去加载。

构造方法 - 每次创建对象时先调用此方法,适合在使用对象前做一些初始化工作

class 类名{
  function __construct(){
parent::__construct(); // 调用父类构造方法
} }

析构方法 - 在某个对象所有引用被删除或当对象被显式销毁时执行

class 类名{
  function __destruct(){
    parent::__destruct();  // 调用父类析构方法
  }  
}

访问控制 - 针对属性和方法

public 公有 ,在任何地方都可以访问

protected 受保护,在类内部、子类、父类中可访问。

private 私有,只能在自身类内部访问。

范围解析操作符 ::      

可用于访问静态成员、类常量、调用父类中被覆盖的方法。

static - 声明类属性或方法为静态,就可以不实例化而直接访问

静态属性不能通过一个类已实例化的对象来访问,但是静态方法可以。

$this不能在静态方法中使用。

静态属性不能使用 -> 操作符访问

抽象类 abstract - 不能被实例化

任何一个类,如果类中只要有一个方法被声明为抽象的,那么这个类就必须声明为抽象类。

继承一个抽象类,子类必须继承父类中所有抽象方法。(此外,这些方法的访问控制必须和父类一样或更为宽松)

抽象方法只有方法的声明,没有方法体。

接口 interface 

接口中的所有方法必须是公有的  public ,且只有方法的声明,没有方法体。

类可以通过implements实现多个接口,接口之间用逗号分隔。

类必须实现接口中定义的所有方法。

接口之间也可以有继承关系,通过extends关键实现继承。

接口中可以定义常量,但不能被子接口或子类所覆盖。

 trait  - 代码复用的一种机制

php5.4起

trait本身不能实例化

trait 名称{
   // 属性、方法
}
class 类名{
  use trait名称;  // 多个trait可用逗号分隔
}

优先级:当前类的方法会覆盖trait的方法,trait的方法会覆盖被继承类中的方法。

冲突解决

<?php
trait A {
    public function smallTalk() {
        echo 'a';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }
public function bigTalk(){
echo 'B';
} }
class Talker { use A, B { B::smallTalk insteadof A; // 明确指定使用冲突方法中的哪一个
B::bigTalk as talk; // 为某个方法引入别名 也可以 B::bigTalk as protected; 来改变方法的访问控制
} }?>

trait中使用trait

trait 名称{
   use trait名称; // 多个trait使用逗号分隔
}

匿名类 php7

new class{
  
}

重载

当调用当前环境下未定义或不可见的属性或方法时,重载方法(魔术方法)会被调用。

所有的重载方法都必须声明为public

属性重载

public __set ( string $name , mixed $value ) : void // 在给不可访问属性赋值时,__set() 会被调用
public __get ( string $name ) : mixed // 读取不可访问属性的值时,__get() 会被调用
public __isset ( string $name ) : bool  // 当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用
public __unset ( string $name ) : void  // 当对不可访问属性调用 unset() 时,__unset() 会被调用

// 属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。

方法重载

public __call ( string $name , array $arguments ) : mixed  // 在对象中调用一个不可访问方法时,__call() 会被调用
public static __callStatic ( string $name , array $arguments ) : mixed  // 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用

 遍历对象

foreach($对象名 as $key=>$value){}
// 遍历其可以访问的可见属性

其它方法:实现Iterator接口遍历对象 或 实现IteratorAggregate接口来实现遍历对象

魔术方法

__construct()
__destruct()
__call()
__callStatic()
__get()
__set()
__isset()
__unset()
__sleep()
__wakeup()
__toString()
__invoke()
__set_state()
__clone() 
__debugInfo() 
public __toString ( void ) : string // 用于一个类被当成字符串时应怎样回应
public __invoke ([ $... ] ) : mixed // 当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用
public static __set_state ( array $properties ) : object // 自 PHP 5.1.0 起当调用 var_export() 导出类时,此静态 方法会被调用
public __debugInfo ( void ) : array
public __sleep ( void ) : array  // serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。该方法常用于提交未提交的数据,或类似的清理操作
public __wakeup ( void ) : void  // unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。

final  如果父类方法被声明为final,子类无法覆盖该方法。如果类被声明为final,则不能被继承。

对象复制

$copy_of_object = clone $object;

当对象复制后,PHP5会对对象所有的属生执行一个浅复制.所有的引用属性,仍会是一个指向原来变量的引用.

当复制完成后,如果定义了__clone()方法,则复制的对象中的__clone()方法会被调用.

对象比较

当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等

而如果使用全等运算符(===),这两个对象变量一定要指向某个类的同一个实例(即同一个对象)。

类型结束

函数的参数可以指定必须为 对象/接口/数组/callable

后期静态绑定

php5.3

用于在继承范围内引用静态调用的类.

使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类:

static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。

对象与引用

$objA -> 标识符A -> 对象内容A

$objB = $objA;

$objB->标识符B->对象内容A (其中 标签符B=标识符A)

对象序列化

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。

unserialize()函数能够重新把字符串变回php原来的值。为了能够unserialize()一个对象,这个对象的类必须已经定义过。

序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

posted on 2020-05-22 13:50  TabPHP  阅读(103)  评论(0)    收藏  举报