Rumah > Artikel > pembangunan bahagian belakang > PHP中的面向对象
访问控制(可见性)
PHP的访问控制有 public(公有),protected(受保护)和 private(私有)
被定义为公有的类成员可以在任何地方被访问。
被定义为受保护的类成员则可以被其自身以及其子类和父类访问。
被定义为私有的类成员则只能被其定义所在的类访问。
不能用于修饰class
类属性不能省略,必须定义为公有,受保护,私有之一。
类中的方法如果没有设置这些关键字,则该方法默认为公有。
同一个类的对象即使不是同一个实例也可以互相访问对方的私有与受保护成员。这是由于在这些对象的内部具体实现的细节都是已知的。
属性
用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性。静态属性则是用 ::(双冒号):self::$property 来访问
$this 是一个到主叫对象的引用
类常量
可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号
常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用
用双冒号::访问
<code>const constant = 'constant value'; </code>
自动加载类
很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含文件列表(每个类一个文件)。
在 PHP 5 中,不再需要这样了。可以定义一个 spl_autoload_register()
函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。
<code><?php // function __autoload($class) { // include 'classes/' . $class . '.class.php'; // } function my_autoloader($class) { include 'classes/' . $class . '.class.php'; } spl_autoload_register('my_autoloader'); // 或者,自 PHP 5.3.0 起可以使用一个匿名函数 spl_autoload_register(function ($class) { include 'classes/' . $class . '.class.php'; }); ?> </code>
构造函数和析构函数
构造函数和析构函数不会被引擎暗中调用。要执行父类的构造函数和析构函数,必须在子类的构造函数体和析构函数体中显式调用 parent::__construct(); parent::__destruct()
继承
除非使用了自动加载,否则一个类必须在使用之前被定义。如果一个类扩展了另一个,则父类必须在子类之前被声明。此规则适用于类继承其它类与接口。
继承使用extends
关键字
范围解析操作符(::)
范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量
Static(静态)关键字
声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
静态属性和方法默认为公有
抽象类
使用关键字abstract
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)
接口
接口是通过 interface 关键字
接口中定义的所有方法都必须是公有,这是接口的特性
接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。
接口也可以继承接口
Traits
自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits。
<code><?php trait ezcReflectionReturnInfo { function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ } } class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */ } class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */ } ?> </code>
通过逗号分隔,在 use 声明列出多个 trait
<code><?php trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo 'World'; } } class MyHelloWorld { use Hello, World; public function sayExclamationMark() { echo '!'; } } ?> </code>
魔术方法
__construct()
__destruct()
__call()
__callStatic()
__get()
__set()
__isset()
__unset()
__sleep() serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。
__wakeup() unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法
__toString() 用于一个类被当成字符串时应怎样回应
__invoke() 当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用
__set_state() 当调用 var_export() 导出类时,此静态 方法会被调用
__clone()
__debugInfo() var_dump()一个对象时调用
这些函数在 PHP 中被称为”魔术方法”(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。
在给不可访问属性赋值时,__set() 会被调用。
读取不可访问属性的值时,__get() 会被调用。
当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
当对不可访问属性调用 unset() 时,__unset() 会被调用。
在对象中调用一个不可访问方法时,__call() 会被调用。
用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。
Final 关键字
如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
属性不能被定义为 final,只有类和方法才能被定义为 final
对象复制
对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。
对象比较
当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等。
而如果使用全等运算符(===),这两个对象变量一定要指向某个类的同一个实例(即同一个对象)。
类型约束
PHP 5 可以使用类型约束。函数的参数可以指定必须为对象(在函数原型里面指定类的名字),接口,数组(PHP 5.1 起)或者 callable(PHP 5.4 起)。不过如果使用 NULL 作为参数的默认值,那么在调用函数的时候依然可以使用 NULL 作为实参。
类型约束不能用于标量类型如 int 或 string。Traits 也不允许。
类型约束不只是用在类的成员函数里,也能使用在函数里
对象序列化
所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法。
版权声明:本文为博主原创文章,未经博主允许不得转载。
以上就介绍了PHP中的面向对象,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。