本文汇总了PHP面向对象程序设计的精要知识,深入解析继承、重载、访问控制、魔术方法及接口等核心特性。通过代码实例明确了$this、self与parent的语义区别,以及私有属性访问、对象克隆和构造函数调用的具体行为,旨在帮助开发者构建规范的PHP类结构。
继承体系与访问控制
在PHP中,使用 extends 关键字实现类的继承。子类可以继承父类的方法与属性,并可通过重写(Overriding)来改变父类行为的定义。需要注意的是,PHP中的“重载”并非传统意义上的多态参数重载,而是指子类实现与父类同名方法或属性的过程。
成员可见性决定了外部如何访问类的属性与方法:
- public:公有成员可在任何地方被访问。
- protected:受保护成员仅可在类内部及子类中被访问,外部不可见但可被继承。
- private:私有成员仅在当前类内部有效,无法被子类继承或外部直接访问。
第1步:理解作用域解析操作符 (::)
目的:明确静态成员、常量及父类成员的访问路径。
入口:在类定义或外部代码中使用。可以使用范围解析操作符(Paamayim Nekudotayim),即双冒号 :: 来访问静态成员、方法和常量,或在子类中覆盖父类成员。
复制代码 代码如下:
class MyClass {
const CONST_VALUE = 'A constant value';
}
echo MyClass::CONST_VALUE;
class OtherClass extends MyClass
{
public static $my_static = 'static var';
public static function doubleColon() {
echo parent::CONST_VALUE . "\n";
echo self::$my_static . "\n";
}
}
OtherClass::doubleColon();
//子类覆盖父类
class MyClass
{
protected function myFunc() {
echo "MyClass::myFunc()\n";
}
}
class OtherClass extends MyClass
{
// 覆盖父类中的方法
public function myFunc()
{
// 但仍然可以调用已被覆盖的方法
parent::myFunc();
echo "OtherClass::myFunc()\n";
}
}
$class = new OtherClass();
$class->myFunc();
第2步:区分 this、self 与 parent
目的:准确引用当前对象、当前类作用域及父类作用域。
入口:在类的方法体内进行变量或函数调用。
$this:指向当前对象的实例指针。它不指向任何特定类,仅代表当前活动的对象实体。
self:指向当前类的作用域。它用于访问类内部的静态变量或非静态成员(需配合 :: 访问静态)。关键点在于:self 不识别继承层次,当在扩展类中使用 self 引用非静态方法时,调用的是扩展类本身的重载方法,而非父类方法。
parent:指向当前类的父类作用域。通常用于在子类中显式调用父类的构造函数或方法。
示例如下:
复制代码 代码如下:
private static $firstCount = 0;
private $lastCount;
//构造函数
function __construct()
{
$this->lastCount = ++self:$firstCount; //使用self来调用静态变量,使用self调用必须使用::(域运算符号)
}
复制代码 代码如下:
//继承类的构造函数
function __construct( $personSex, $personAge )
{
parent::__construct( "test" ); //使用parent调用了父类的构造函数
$this->personSex = $personSex;
$this->personAge = $personAge;
}
魔术方法与动态属性处理
PHP以两个下划线 __ 开头的方法被称为魔术方法。建议在自定义方法时避免使用此前缀,以免与系统预留功能冲突。
第3步:实现私有属性的自动访问器
目的:允许在类外部像访问公共属性一样安全地获取或设置私有/受保护属性,同时执行预定义逻辑。
动作:在类中定义 __get()、__set()、__isset() 和 __unset() 方法。这些方法由PHP引擎在特定场景下自动触发,而非手动调用。
复制代码 代码如下:
<?php
class Person{
//下面是人的成员属性
private $name; //人的名字
private $sex; //人的性别
private $age; //人的年龄
//__get()方法用来获取私有属性
private function __get($property_name){
if(isset($this->$property_name)){
return($this->$property_name);}else {
return(NULL);
}
}
}
//__set()方法用来设置私有属性
private function __set($property_name, $value){
$this->$property_name = $value;
}
//__isset()方法
private function __isset($nm){
echo "isset()函数测定私有成员时,自动调用<br>";
return isset($this->$nm);
}
//__unset()方法
private function __unset($nm){
echo "当在类外部使用unset()函数来删除私有成员时自动调用的<br>";
unset($this->$nm);
}
}
$p1=new Person();
$p1->name="this is a person name";
//在使用isset()函数测定私有成员时,自动调用__isset()方法帮我们完成,返回结果为true
echo var_dump(isset($p1->name))."<br>";
echo $p1->name."<br>";
//在使用unset()函数删除私有成员时,自动调用__unset()方法帮我们完成,删除name私有属性
unset($p1->name);
//已经被删除了, 所这行不会有输出
echo $p1->name;
?>
类生命周期管理与特殊关键字
对象的创建与销毁涉及构造函数与析构函数的配合,而 final 关键字则提供了不可变性的约束。
第4步:管理构造函数与类锁定
目的:控制对象初始化流程并确保类结构的稳定性。
注意:如果子类定义了 __construct() 方法,父类的构造函数将不再被自动调用。若需执行父类初始化,必须在子类构造中显式调用 parent::__construct()。
关于构造函数调用的逻辑总结如下:
| 父类 |
子类 |
结果 |
| 有构造函数 |
无构造函数 |
父构造 |
| 有构造函数 |
有构造函数 |
子构造 |
析构函数 (__destruct()):在对象所有引用被删除或对象被显式销毁时执行,常用于资源清理工作。
final 关键字:
1. 标记为 final 的方法不能被子类覆盖。
2. 标记为 final 的类不能被继承。
对象克隆与接口定义
第5步:安全克隆与接口契约
目的:复制现有对象以满足不同上下文需求,或通过接口定义标准化的行为规范。
入口:使用 clone 关键字或定义 interface。
对象克隆:
使用 clone 操作符复制对象。PHP默认执行“浅复制”(Shallow Copy),即属性中的引用仍然指向原变量。若需在克隆过程中修改属性值,可定义 __clone() 方法并在其中进行重置。
接口 (Interface):
接口类似于特殊的抽象类,强制实现类遵循特定的契约。关键规则包括:
- 接口中的所有方法必须是
public 且为空(无主体)。
- 实现多个接口时,方法名不能冲突。
- 接口支持继承,使用
extends 操作符。
- 接口中可以定义常量,其值为编译期确定的常数,且不可被子类或子接口修改。
复制代码 代码如下:
// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// 实现接口
// 下面的写法是正确的
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
以上就是PHP面向对象精要的详细内容,更多关于PHP面向对象程序设计技巧的资料请关注本站其它相关文章!