PHP 进阶之 类(Class)

属性

类的变量成员叫做“属性”,或者叫“字段”、“特征”,在本文档统一称为“属性”。属性声明是由关键字 publicprotected 或者 private 开头,然后跟一个普通的变量声明来组成。属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指 PHP 脚本在编译阶段时就可以得到其值,而不依赖于运行时的信息才能求值。

在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。静态属性则是用 ::(双冒号):self::$property 来访问

类常量

可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。

常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用,可以是数组

class Test {
    const COLOR = array('yellow','white','black');
    function showColor(){
        var_dump(self::COLOR);
    }
}
  • 常量与属性一样,可以被继承
  • 接口中也可以定义常量

自动加载

  在 PHP 5 中, spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

扫描二维码关注公众号,回复: 115791 查看本文章

  spl_autoload_register() 参数是一个回调函数,可以注册多次,例如

<?php
// MyClass 位于 ./MyClass/MyClass.php 下,同时MyClass继承 ./MyClass1/MyClass1.php中的 MyClass1 

function load_MyClass($class_name)
{
    // 引用前一定要判断文件是否存在,避免文件不存在报错
    if (file_exists('MyClass/' . $class_name . '.php')){
        require_once 'MyClass/' . $class_name . '.php';
    }
}
function load_MyClass1($class_name)
{
    if (file_exists('MyClass1/' . $class_name . '.php')){
        require_once 'MyClass1/' . $class_name . '.php';
    }
}

spl_autoload_register('load_MyClass');
spl_autoload_register('load_MyClass1');

$c = new MyClass();
$c->say();
    

构造函数

public function __construct ([ mixed $args [, $... ]] )
  • 如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用parent::__construct()。
  • 如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
  • 子类构造函数参数可以和父类中不一样 (其他方法不行)
  • 构造函数中不能使用 return 返回结果,因为这样会终结此次请求

析构函数

public function __destruct ( void )

析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。

继承

当扩展一个类,子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被继承的方法都会保留其原有功能。

  • 除非使用了自动加载,否则一个类必须在使用之前被定义。如果一个类扩展了另一个,则父类必须在子类之前被声明。此规则适用于类继承其它类与接口。
  • PHP 不支持多继承 , 但不意味着子类不能继承多个父类,我们可以通过继承一个父类,父类继承另一个父类的方法实现
    class A {
            // more code here
    }
    
    class B extends A {
            // more code here
    }
    
    class C extends B {
            // more code here
    }

重写

当一个子类覆盖其父类中的方法时,PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。子类可以通过 parent 手动调用

class MyClass
{
    protected function myFunc() {
        echo "MyClass::myFunc()\n";
    }
}

class OtherClass extends MyClass
{
    // 覆盖了父类的定义
    public function myFunc()
    {
        // 但还是可以调用父类中被覆盖的方法
        parent::myFunc();
        echo "OtherClass::myFunc()\n";
    }
}

范围解析操作符

范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法

当在类定义之外引用到这些项目时,要使用类名

静态属性 Static 关键字

就像其它所有的 PHP 静态变量一样,静态属性只能被初始化为文字或常量,不能使用表达式。所以可以把静态属性初始化为整数或数组,但不能初始化为另一个变量或函数返回值,也不能指向一个对象

调用静态属性:self::  static::

区别

  • self 指向定义时指向的class
  • static 指向调用时的class , 作用于$this 一样 ,但是$this 不能调用静态属性和方法
    class a{
    
    static protected $test="class a";
    
    public function static_test(){
    
    echo static::$test; // Results class b
    echo self::$test; // Results class a
    
    }
    
    }
    
    class b extends a{
    
    static protected $test="class b";
    
    }
    
    $obj = new b();
    $obj->static_test();

匿名类

PHP7 支持通过 new class 来实例化一个匿名类,这可以用来替代一些"用后即焚"的完整类定义。

<?php 
interface Logger { 
   public function log(string $msg); 
} 
 
class Application { 
   private $logger; 
   public function getLogger(): Logger { 
      return $this->logger; 
   } 
 
   public function setLogger(Logger $logger) { 
      $this->logger = $logger; 
   }   
} 
 
$app = new Application; 
 
// 使用 new class 创建匿名类 
$app->setLogger(new class implements Logger { 
   public function log(string $msg) { 
      print($msg); 
   } 
}); 
 
$app->getLogger()->log("我的第一条日志"); 
 
?>

猜你喜欢

转载自www.cnblogs.com/xiaoliwang/p/8997933.html