當您擴展一個類時,除了任何子定義之外,子類還可以調用父類的所有公共和受保護的方法和屬性。如果您不需要重寫父的方法,而只是希望地方使用它們的孩子裏面,使用
public function somethingUsingExecute()
{
$query = $this->Execute("SELECT * FROM $table");
…
}
如果您需要在子類覆蓋execute
也想調用該方法與母公司的原始功能,使用
public function execute($table)
{
// can do something not in parent before parent call
$query = parent::Execute("SELECT * FROM $table");
// can do something not in parent after parent call
}
的靜態調用
$query = DBManager::Execute("SELECT * FROM $table");
是你應該忘記它存在的原因,因爲你正在將一個類名硬編碼到using類中,並將方法調用耦合到全局作用域。兩者都很難測試和維護。我不會詳細討論,因爲這已經在SO之前討論過了。只要給它一個搜索。
關於該User/DBManager示例的「最佳技巧」根本不會使用繼承。繼承創建一個is-a關係。孩子是父母的特例。但用戶不是一個DBManager(我會稱它爲DbAdapter btw)。
DBManager類的職責是允許訪問數據庫。你的用戶沒有這個責任。它使用 DBManager來訪問數據庫,但它確實需要知道如何做到這一點。DBManager已經做到了。
任何類別使用應該注入/聚合另一個類。所以,你應該做的是:
class User …
protected $db;
protected $isAuthenticated = FALSE;
public function __construct($db)
{
$this->db = $db;
}
public function authenticate($username, $password)
{
if($this->db->query('SELECT … ')) {
$this->isAuthenticated = TRUE;
}
return $this->isAuthenticated;
}
…
}
然後,你可以做
$db = new DBManager;
$john = new User($db);
$john->authenticate('JohnDoe', 'jd/12345');
$jane = new User($db);
$jane->authenticate('JaneDoe', 'jd/67890');
$logger = new DBLogger($db);
$logger->log('something to db');
注入DB類具有您可以在其他使用類重用現有DBManager實例的好處。如果擴展DBManager類,則每個新實例都將創建一個到數據庫的新連接,這是出於性能原因而不受歡迎的。
如果你重寫執行函數,你需要使用$ this,如果不是,我認爲其他選項是最好的方式,我不知道[parentClassName]或父類之間是否存在任何差異,但我會選擇第二個一 – raultm 2011-01-29 11:07:25