Skip to content

重写、重载 ​

override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。

重写(覆盖)的规则:    1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载.    2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。    3、重写的方法的返回值必须和被重写的方法的返回一致;    4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;    5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写

6、静态方法不能被重写为非静态的方法(会编译出错)。

overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。

重载的规则:    1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样);    2、不能通过访问权限、返回类型、抛出的异常进行重载;    3、方法的异常类型和数目不会对重载造成影响;

PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法。我们是通过魔术方法(magic methods)来实现的。

php
class A{
  public function test(){
    echo "11";
  }
}

class B extends A{
  #重写父类的方法
  public function test(){
    echo "22";
  }
}

class C{
  public function __call($name,$args) {
    echo $name;
  }
  public function __callStatic($name, $arguments){}
}

多态 ​

多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。

php
abstract class animal{
    abstract function fun();
}
class cat extends animal{
    function fun(){
        echo "cat say miaomiao...";
    }
}
class dog extends animal{
    function fun(){
        echo "dog say wangwang...";
    }
}
function work($obj){
    if($obj instanceof animal){
        $obj -> fun();
    }else{
        echo "no function";
    }
}
work(new dog()); 
work(new cat());

遍历对象 ​

遍历对象可以使用foreach遍历可见属性。或者实现iterator接口

php
class MyClass
{
    public $var1 = 'value 1';
    public $var2 = 'value 2';
    public $var3 = 'value 3';

    protected $protected = 'protected var';
    private   $private   = 'private var';

}
$c = new MyClass();

foreach ($c as $key=>$v) {
  echo $key."=>"$v;
}

魔术方法 ​

  • __construct 初始化调用
  • __desturct 对象销毁时调用
  • __call 访问一个不存在的方法的时候调用
  • __callStatic 访问一个不存在的静态方法调用
  • __get() 访问一个不存在的属性调用
  • __set() 修改一个不存在的属性调用
  • __isset() 使用isset判断一个高属性的时候调用
  • __toString() 当一个对象以一个字符串返回时候触发调用
  • __invoke()当把一个对象当初函数去调用的时候 触发

final ​

final 最终的,如果一个类被定位成final 这个类不能被继承。如果一个方法被定义一个final。这个方法不能被覆盖。

final不能修饰属性。

php
class A{
	final public function test(){}
}

Class B extends A{
  public function test(){ //error
    
  }
}

对象复制、对象比较 ​

对象复制可以通过 clone 关键字来完成

当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。

php
class A{

	public $name = "hello";
}

$a  = new A();

$b = clone $a;

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

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

类型约束 ​

函数的参数可以指定必须为对象(在函数原型里面指定类的名字),接口,数组

php
function Test(A $a){}

后期静态绑定 ​

“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用

self的限制

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

php

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        self::who();
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}//

B::test();//A
#静态绑定语法
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who();
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}//

B::test();//B
## 实现ar model
class Model 
{ 
    public static function find() 
    { 
        echo static::$name; 
    } 
} 

class Product extends Model 
{ 
    protected static $name = 'Product'; 
} 

Product::find();

对象和引用 ​

PHP 的引用是别名,就是两个不同的变量名字指向相同的内容。在 PHP 5,一个对象变量已经不再保存整个对象的值。只是保存一个标识符来访问真正的对象内容。 当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,另外一个变量跟原来的不是引用的关系,只是他们都保存着同一个标识符的拷贝,这个标识符指向同一个对象的真正内容。

php
class A {
    public $foo = 1;
}  

$a = new A;
$b = $a;     // $a ,$b都是同一个标识符的拷贝
             // ($a) = ($b) = <id>
$b->foo = 2;
echo $a->foo."\n";

对象序列化 ​

在会话中存储对象。使用serialize序列化。

基于 VitePress 构建 · 欢迎 Star 与 PR