
php 类继承允许子类访问父类的公共属性和方法,但每个对象实例的属性值相互独立;若未为子类实例显式赋值,其继承的公共属性默认为 null,需手动初始化或通过构造函数传递。
php 类继承允许子类访问父类的公共属性和方法,但每个对象实例的属性值相互独立;若未为子类实例显式赋值,其继承的公共属性默认为 null,需手动初始化或通过构造函数传递。
在 PHP 面向对象编程中,extends 关键字使子类继承父类的结构(属性与方法声明),而非运行时状态(属性的具体值)。这意味着:
- ✅ 子类
B可以直接调用parent::testParent()或访问$this->nilai; - ❌ 但
$this->arrayperk在B的新实例中初始值为null,即使父类A的同名属性已被其他实例赋值——因为每个对象拥有独立的属性存储空间。
你原始代码的问题根源正在于此:
$arrayperk = [1 => 'array1', 2 => 'array2']; $class_a = new A(); $class_a->arrayperk = $arrayperk; // ✅ 仅设置 class_a 实例的 arrayperk $class_b = new B(); // ❌ class_b 实例的 arrayperk 仍为 null(未初始化)
因此 print_r($class_b->coba()) 返回空结果,并非方法调用失败,而是 $this->arrayperk 本身为空。
✅ 正确做法:为子类实例显式赋值或统一初始化
方案一:手动赋值(快速修复)
$class_b = new B(); $class_b->arrayperk = $arrayperk; // 显式设置子类实例的属性 echo $class_b->coba(); // 输出: Array ( [1] => array1 [2] => array2 )
方案二:通过构造函数自动初始化(推荐,更健壮)
修改父类 A,接受可选参数并在构造中赋值:
class A
{
public $arrayperk;
public $nilai;
function __construct($arrayperk = [])
{
$this->arrayperk = $arrayperk;
$this->nilai = 'This is bad';
}
function testParent()
{
return $this->arrayperk;
}
function testA()
{
return number_format(1000);
}
}
class B extends A
{
// 可选择重写构造函数,确保兼容父类逻辑
function __construct($arrayperk = [])
{
parent::__construct($arrayperk); // ✅ 自动继承初始化逻辑
}
function coba()
{
return $this->testParent();
}
function coba2()
{
return $this->testA();
}
function coba3()
{
return $this->nilai;
}
}
使用方式:
$arrayperk = [1 => 'array1', 2 => 'array2']; $class_b = new B($arrayperk); // ✅ 构造时传入,自动初始化 print_r($class_b->coba()); // 正确输出数组
? 调试建议:善用 var_dump() 检查实际值
避免仅依赖 print_r(),尤其对可能为 null 的变量:
var_dump($class_b->arrayperk); // 直观显示 NULL 或 array(...)
⚠️ 注意事项总结
- 继承 ≠ 共享数据:子类继承的是“属性定义”,不是“属性值”;
- 所有
public属性均可被子类实例直接访问(如$this->arrayperk),无需parent::前缀; - 若需强制初始化,优先在
__construct()中处理,而非依赖外部赋值; -
protected属性也可被子类访问,但不可从类外部直接读写,适合封装内部状态。
通过理解“实例独立性”这一核心机制,你就能准确控制属性在继承链中的行为,写出更可靠、可维护的 PHP OOP 代码。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











