PHP 手册 (类与对象) 学习笔记一:基本概念

关键词:class
定义:每个类的定义都以关键字 class 开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义
规则:类名可以是任何非 PHP 保留字的合法标签。一个合法类名以字母或下划线开头,后面跟着若干字母,数字或下划线
包含:一个类可以包含有属于自己的常量,变量(称为“属性”)以及函数(称为“方法”)
Example 1:简单的类定义

<?php
   class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }
?>

备注:当一个方法在类定义内部被调用时,有一个可用的伪变量 $this。$this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)
Example 2:伪变量的示例

   class A
   {
       function foo()
       {
           if(isset($this)) {
                echo "\$this is defined (";
                echo get_class($this);
                echo ")\n";
           } else {
                echo "\$this is not defined.\n";
           }
       }
   }

   class B
   {
       function bar()
       {
           A::foo();
       }
   }

   $a = new A();
   $a->foo();//$this is defined (A)
    A::foo();//$this is not defined
    $b = new B();
    $b->bar();//PHP 5.6: $this is defined (B) PHP 7:$this is not defined(没有测试过)
    B::bar();//$this is defined (B)

关键词:new
概念:要创建一个类的实例,必须使用 new 关键字。当创建新对象时该对象总是被赋值,除非该对象定义了构造函数并且在出错时抛出了一个异常。类应在被实例化之前定义(某些情况下则必须这样)。

如果在 new 之后跟着的是一个包含有类名的字符串 string,则该类的一个实例被创建。如果该类属于一个命名空间,则必须使用其完整名称。
Example 3:创建实例

   class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }

   $instance = new SimpleClass();

   //也可以:
    $className = 'SimpleClass';
    $instance = new $className;

在类定义内部,可以用 new self 和 new parent 创建新对象。
当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。此行为和给函数传递入实例时一样。可以用克隆给一个已创建的对象建立一个新实例。
Example 4:对象赋值

  class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }

   $instance = new SimpleClass();
   $assigned = $instance;
   $reference = & $instance;
   $instance->var = '$assigned will have this value';
   $instance = null;
   var_dump($instance);//NULL
   var_dump($assigned);
   /*object(SimpleClass)#1 (1) {
["var"]=>
     string(30) "$assigned will have this value"
}*/
   var_dump($reference);//NULL

Example 5:创建新对象

  class Test
    {
        static public function getNew()
        {
            return new static;
        }
    }

    class Child extends Test
    {}
    $obj1 = new Test();
    $obj2 = new $obj1;
    var_dump($obj1 !== $obj2);//bool(true)
    $obj3 = Test::getNew();
    var_dump($obj3 instanceof Test);//bool(true)
    $obj4 = Child::getNew();
    var_dump($obj4 instanceof Child);//bool(true)
    var_dump($obj4 instanceof Test);//bool(true)

Example 6:访问新创建对象的成员

echo (new DateTime())->format('Y');//2020

关键词:属性和方法
Example 7:属性名和方法的调用

   class Foo
    {
        public $bar = 'property';

        public function bar()
        {
            return 'method';
        }
    }
    $obj = new Foo();
    echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
    /*
    property
    method
    */

Example 7:属性里存储匿名函数

class Foo1
    {
        public $bar;
        public function __construct()
        {
            $this->bar = function(){
                return 42;
            };
        }
    }

    $obj = new Foo1;
    $func = $obj->bar;
    echo $func(), PHP_EOL;//42
    echo ($obj->bar)(), PHP_EOL;//PHP 5.6运行报错,PHP7可以(没试过)

关键词:extends
一个类可以在声明中用 extends 关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类

被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。

当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。
Example 9:简单的类继承

   class SimpleClass
   {
       public $var = 'a default value';

       public function displayVar()
       {
           echo $this->var;
       }
   }


    class ExtendClass extends SimpleClass
    {
        public function displayVar()
        {
            echo "Extending class\n";
            parent::displayVar();
        }
    }

    $extended = new ExtendClass();
    $extended->displayVar();
    /*
    Extending class
    a default value
    */

关键词:::class
自 PHP 5.5 起,关键词 class 也可用于类名的解析。使用 ClassName::class 你可以获取一个字符串,包含了类 ClassName 的完全限定名称。这对使用了 命名空间 的类尤其有用。
Example 10:类名的解析

    namespace NS {
        class ClassName
        {}
        echo ClassName::class, PHP_EOL;//NS\ClassName
    }

补充:get_class()和get_called_class()的区别

class Foo{
    public function test(){
        var_dump(get_class());
    }

    public function test2(){
        var_dump(get_called_class());
    }

    public static function test3(){
        var_dump(get_class());
    }

    public static function test4(){
        var_dump(get_called_class());
    }
}

class B extends Foo
{}

$foo = new Foo();
$foo->test();//string(3) "Foo"
$foo->test2();//string(3) "Foo"

$B = new B();
$B->test();//string(3) "Foo"
$B->test2();//string(3) "B"

Foo::test3();//string(3) "Foo"
Foo::test4();//string(3) "Foo"

B::test3();//string(3) "Foo"
B::test4();//string(3) "B"

get_class (): 获取当前调用方法的类名;
get_called_class():获取静态绑定后的类名;
附原文手册连接:本文代码全部手敲验证

PHP手册(类与对象)学习笔记一:基本概念

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!