一.final
这个关键字只能用来定义类和定义方法, 不能使用final这个关键字来定义成员属性,因为final是常量的意思,我们在PHP里定义常量使用的是define()函数,所以不能使用final来定义成员属性。
使用final关键标记的类不能被继承;
<?php final class Person { function say() { } } class Student extends Person { function say() { } } ?>
会出现下面错误:
Fatal error: Class Student may not inherit from final class (Person)
使用final关键标记的方法不能被子类覆盖,是最终版本;
<?php
class Person {
final function say() {
}
}
class Student extends Person {
function say() {
}
}
?>
会出现下面错误:
会出现下面错误:
Fatal error: Cannot override final method Person::say()
类型的访问修饰符允许开发人员对类成员的访问进行限制,这是PHP5的新特性,但却是OOP语言的一个好的特性。而且大多数OOP语言都已支持此特性。PHP5支持如下3种访问修饰符:
public (公有的、默认的),protected (受保护的)和private (私有的)三种。
public 公有修饰符,类中的成员将没有访问限制,所有的外部成员都可以访问(读和写)这个类成员(包括成员属性和成员方法),在PHP5之前的所有版本中,PHP 中类的成员都是public的,而且在PHP5中如果类的成员没有指定成员访问修饰符,将被视为public 。例:
public $name; public function say(){ };
private 私有修改符,被定义为private的成员,对于同一个类里的所有成员是可见的,即没有访问限制;但对于该类的外部代码是不允许改变甚至读操作,对于该类的子类,也不能访问private修饰的成员。例:
private $var1 = 'A'; // 属性 private function getValue(){ } // 函数
类内部访问方式为:$this->var1,$this->getValue()
protected保护成员修饰符,被修饰为protected的成员不能被该类的外部代码访问。但是对于该类的子类有访问权限,可以进行属性、方法的读及写操作,该子类的外部代码包括其的子类都不具有访问其属性和方法的权限。
private | protected | public | |
同一个类中 | √ | √ | √ |
类的子类中 | √ | √ | |
所有的外部成员 | √ |
属性访问控制示例:
<?php /** * Define MyClass */ class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj = new MyClass(); echo $obj->public; // Works echo $obj->protected; // Fatal Error echo $obj->private; // Fatal Error $obj->printHello(); // Shows Public, Protected and Private /** * Define MyClass2 */ class MyClass2 extends MyClass { // We can redeclare the public and protected method, but not private protected $protected = 'Protected2'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj2 = new MyClass2(); echo $obj->public; // Works echo $obj2->private; // Undefined echo $obj2->protected; // Fatal Error $obj2->printHello(); // Shows Public, Protected2, not Private
方法访问控制示例:
<?php /** * Define MyClass */ class MyClass { // Contructors must be public public function __construct() { } // Declare a public method public function MyPublic() { } // Declare a protected method protected function MyProtected() { } // Declare a private method private function MyPrivate() { } // This is public function Foo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); } } $myclass = new MyClass; $myclass->MyPublic(); // Works $myclass->MyProtected(); // Fatal Error $myclass->MyPrivate(); // Fatal Error $myclass->Foo(); // Public, Protected and Private work /** * Define MyClass2 */ class MyClass2 extends MyClass { // This is public function Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // Fatal Error } } $myclass2 = new MyClass2; $myclass2->MyPublic(); // Works $myclass2->Foo2(); // Public and Protected work, not Private
另外在子类覆盖父类的方法时也要注意一点,子类中方法的访问权限一定不能低于父类被覆盖方法的访问权限,也就是一定要高于或等于父类方法的访问权限。
例如,如果父类方法的访问权限是protected,那么子类中要覆盖的权限就要是protected和public,如果父类的方法是public那么子类中要覆盖的方法只能也是public,总之子类中的方法总是要高于或等于父类被覆盖方法的访问权限。