我首先對grrbrr404說「謝謝」。他給了我一些想法,讓我開始朝着正確的方向發展。
我終於解決該解決方案是以下幾點:
function inherit_this() {
$bt = debug_backtrace();
call_user_func(array($this, get_parent_class($bt[1]['class']) . '::do_something'));
}
這不是漂亮(我特別討厭呼籲debug_backtrace()
此),但它一直設置到這個$對象上下文,並處理情況該方法從對象層次結構中間的某個方法調用。
對於那些發現我的例子令人困惑和/或想知道「爲什麼你想要這樣做?」我很抱歉,並提供了下面的附加例子,這有希望更具說明性,更接近原始問題。這是相當長的時間,但希望說明爲什麼我關心保持$這個設置正確,也說明了爲什麼我不能硬編碼任何特定的類名或使用$ this-> method()。避免無限循環始終是我的首要任務。 :-)
class class1_required_type { }
class class2_required_type { }
class class3_required_type { }
class class4_required_type { }
class class1 {
protected $data = array();
protected function checkType($name, $value, $requiredType) {
print "In class1::checkType()\n";
if (get_class($value) === $requiredType) {
$backtrace = debug_backtrace();
call_user_func(array($this, get_parent_class($backtrace[1]['class']) . "::mySet"), $name, $value);
} else {
throw new Exception(get_class($this) . "::mySet('" . $name . "') requires an object of type '" . $requiredType . "', but got '" . get_class($value) . "'");
}
}
function mySet($name, $value) {
print "In class1::mySet()\n";
if ($name === 'class1_field') {
$this->checkType($name, $value, 'class1_required_type');
} else {
$this->data[$name] = $value;
}
}
function dump() {
foreach ($this->data as $key => $value) {
print "$key: " . get_class($value) . "\n";
}
}
}
class class2 extends class1 {
function mySet($name, $value) {
print "In class2::mySet()\n";
if ($name === 'class2_field') {
$this->checkType($name, $value, 'class2_required_type');
} else {
parent::mySet($name, $value);
}
}
}
class class3 extends class2 {
function mySet($name, $value) {
print "In class3::mySet()\n";
if ($name === 'class3_field') {
$this->checkType($name, $value, 'class3_required_type');
} else {
parent::mySet($name, $value);
}
}
}
class class4 extends class3 {
function mySet($name, $value) {
print "In class4::mySet()\n";
if ($name === 'class4_field') {
$this->checkType($name, $value, 'class4_required_type');
} else {
parent::mySet($name, $value);
}
}
}
$obj = new class4;
$obj->mySet('class3_field', new class3_required_type);
$obj->dump();
我試圖避免「checkType()」函數的重複,但仍提供即使在層次結構得到任意大的正確的行爲。
更爲優雅的解決方案當然是最受歡迎的。
你不能使用php5,然後做一個私有的base_class方法嗎?這意味着繼承類不能覆蓋該方法。 – smack0007
也許,但我實際上是想讓interiting類重寫方法。這實際上是原始代碼的大部分重點。我可能需要重寫這個例子,但它會更長。 –