UNPKG

manual-php

Version:
334 lines (262 loc) 6.32 kB
# 基本语法 每个类的定义都以关键字 `class` 开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。类名可以是任何非 PHP 保留字的合法标签。一个合法类名以字母或下划线开头,后面跟着若干字母,数字或下划线。一个类可以包含有属于自己的常量,变量(属性)以及函数(方法)。 ```php <?php class Foo { /** * Just a test property. * * @var string */ public string $property = 'foo'; /** * Just a test method. * * @param void * @return void */ public function method() { // } } ``` 当一个方法在类定义内部被调用时,有一个可用的伪变量 `$this` 。 `$this` 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。 ```php <?php class Foo { /** * Just a test property. * * @var string */ public string $property = 'foo'; /** * Return the specified property. * * @param void * @return string */ public function method(): string { return $this->property; } } $foo = new Foo(); var_dump($foo->method()); // string(3) "foo" ``` 要创建一个类的实例,必须使用 `new` 关键字。当创建新对象时该对象总是被赋值,除非该对象定义了构造函数并且在出错时抛出了一个异常。类应在被实例化之前定义(某些情况下则必须这样)。如果在 `new` 之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个命名空间,则必须使用其完整名称。 ```php <?php class Foo { // } $foo = new Foo(); var_dump($foo); // object(Foo)#1 (0) { } $foo = 'Foo'; $foo = new $foo; var_dump($foo); // object(Foo)#1 (0) { } $foo = new Foo(); $foo = new $foo; var_dump($foo); // object(Foo)#1 (0) { } ``` 在类定义内部,可以用 `new self` 创建新对象。 ```php <?php class Foo { /** * Return an instance of the current class. * * @param void * @return Foo */ public static function method(): Foo { return new self; } } var_dump(Foo::method()); // object(Foo)#1 (0) { } ``` 在类定义内部,可以用 `new parent` 创建新对象。 ```php <?php class Foo { // } class Bar extends Foo { /** * Return an instance of the parent class. * * @param void * @return Foo */ public static function method(): Foo { return new parent; } } var_dump(Bar::method()); // object(Foo)#1 (0) { } ``` 在类定义内部,可以用 `new static` 创建新对象。 ```php <?php class Foo { /** * Return an instance of the late static binding class. * * @param void * @return Foo */ public static function method(): Foo { return new static; } } class Bar extends Foo { // } $foo = Foo::method(); var_dump($foo); // object(Foo)#1 (0) { } $bar = Bar::method(); var_dump($bar); // object(Bar)#2 (0) { } ``` 当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。 ```php <?php class Foo { // } $foo = new Foo(); $bar = $foo; $baz = &$foo; $foo = null; var_dump($foo); // NULL var_dump($bar); // object(Foo)#1 (0) { } var_dump($baz); // NULL ``` 可以通过一个表达式来访问新创建对象的成员。 ```php <?php class Foo { /** * Just a test property. * * @var string */ public string $property = 'foo'; } var_dump((new Foo())->property); // string(3) "foo" ``` 类中的属性和方法存在于单独的“名称空间”中,因此可以使用具有相同名称的属性和方法。 ```php <?php class Foo { /** * Just a test property. * * @var string */ public string $test = 'property'; /** * Return a string. * * @param void * @return string */ public function test(): string { return 'method'; } } $foo = new Foo(); var_dump($foo->test); // string(8) "property" var_dump($foo->test()); // string(6) "method" ``` 调用存储在属性中的匿名函数。 ```php <?php class Foo { /** * Store an anonymous function. * * @var callable */ public $property; /** * Store an anonymous function to the property. * * @param void * @return void */ public function __construct() { /** * Return a string. * * @param void * @return string */ $this->property = function (): string { return 'foo'; }; } } $foo = new Foo(); $method = $foo->property; var_dump($method()); // string(3) "foo" var_dump(($foo->property)()); // string(3) "foo" ``` 一个类可以在声明中用 `extends` 关键字继承另一个类的方法和属性。 PHP 不支持多重继承,一个类只能继承一个基类。被继承的方法和属性可以通过用同样的名字重新声明来覆盖。但是如果父类定义方法时使用了 `final` ,则该方法不可被覆盖。可以通过 `parent::` 来访问被覆盖的方法或属性。当覆盖方法时,参数必须保持一致否则 PHP 将发出 `E_STRICT` 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。 ```php <?php class Foo { /** * Return a string. * * @param void * @return void */ public function method(): string { return 'foo'; } } class Bar extends Foo { /** * Override the parent method. * * @param void * @return string */ public function method(): string { return 'bar'; } } $bar = new Bar(); var_dump($bar->method()); // string(3) "bar" ``` 关键字 `class` 也可用于类名的解析。使用关键字 `class` 可以获取一个字符串,包含了类的完全限定名称。这对使用了命名空间的类尤其有用。 ```php <?php namespace Foo; class Bar { // } var_dump(Bar::class); // string(7) "Foo\Bar" ```