我有一个抽象类,声明其子元素所需的方法。它还有一个孩子继承的委托人。如何使抽象类影响扩展它的类的子类。为了进一步澄清我的问题,我的情况如下:
<?php
include_once 'database.php';
include_once 'validation.php';
abstract class DataOperations extends DatabaseConnection {
//The error string shared by all children of DataOperations
//This will be the message to be displayed in case validation failure
public $validator;
public $err_valid_string;
/**
* The DataOperations' constructor ensures that all of its children can perform database operation
* by automatically starting it for them. In case a child overrides this constructor, this child
* must explicitly start the connection to prevent fatal errors. Also, $validator must be re-instantiated
*/
public function __construct() {
$this->startDBConnection();
$this->validator = new InputValidator();
}
public function __destruct() {
}
abstract public function validateData();
abstract public function loadRecord($key, $cascade);
abstract public function saveRecord();
abstract public function updateRecord();
abstract public function deleteRecord();
}
?>
现在,这是扩展DataOperations抽象类的子对象
class Guest extends DataOperations {
//some properties here
public function validateData() {
//implementation
}
public function newRecord(implementation) {
//implementation
}
public function loadRecord($key, $cascade){
//implementation
}
public function saveRecord() {
//implementation
}
public function updateRecord() {
//implementation
}
public function deleteRecord() {
//implementation
}
}
?>
这是另一个班,是宾的孩子
class Booking extends Guest {
//some properties here
public function validateData() {
//implementation
}
public function newRecord(implementation) {
//implementation
}
public function loadRecord($key, $cascade){
//implementation
}
public function saveRecord() {
//implementation
}
public function updateRecord() {
//implementation
}
public function deleteRecord() {
//implementation
}
}
?>
问题是,如果我在Booking中删除一个方法,比如deleteRecord(),PHP就不会抛出错误,因为我认为抽象类不会影响它的'孙子'。我怎样才能解决这个问题?我想过使用接口,但我的系统已经有11个类,这些类依赖于抽象类的某些方法。这将需要密集的重构。
答案 0 :(得分:0)
最好和最干净的方法是让你的&#34;预订&#34; class扩展&#34; DATAOPERATIONS&#34; class,而不是GUEST,因为看起来你在BOOKING类中没有任何额外的方法。其他明智的制作和接口并实现它。这不是首选方式,但您必须提供更多信息。
答案 1 :(得分:0)
要清楚,重新声明子类中的方法将在从子类调用时覆盖父类的该方法的实现,同时不影响通过扩展父类提供的任何其他功能:
class a
{
function hello()
{
echo "Hello";
}
function goodbye()
{
echo "Goodbye";
}
}
/**
* class b overwrites class a's implementation of method goodbye but will retain
* it's definition for method hello
*/
class b extends a
{
function goodbye()
{
echo "See ya!";
}
}
$object = new b();
$object->hello(); // Hello
$object->goodbye();// See ya!
您似乎希望跨多个类定义实现一致的接口。如果是这种情况,您可能希望使用PHP的接口进行探索。
这些允许您指定类定义中必须存在的方法及其参数集(统称为签名)。您的类定义将implement
一个接口,如果您的定义不符合接口实现规范,则会抛出致命错误。
从PHP手册:
// Declare the interface 'iTemplate'
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// Implement the interface
// This will work
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;
}
// This will not work
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (iTemplate::getHtml)
class BadTemplate implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}
您可以在PHP手册中找到有关界面的更多信息:
最后,看起来您希望为子类定义一个公共构造函数。您的子类可以在实现单独的接口时扩展DataOperations类:
class Guest extends DataOperations implements DatabaseWriter
...
答案 2 :(得分:0)
正如您自己所说,界面是最适合的解决方案。像
include_once 'database.php';
include_once 'validation.php';
interface DbInterface {
abstract public function validateData();
abstract public function loadRecord($key, $cascade);
abstract public function saveRecord();
abstract public function updateRecord();
abstract public function deleteRecord();
}
class DataOperations extends DatabaseConnection {
//The error string shared by all children of DataOperations
//This will be the message to be displayed in case validation failure
public $validator;
public $err_valid_string;
/**
* The DataOperations' constructor ensures that all of its children can perform database operation
* by automatically starting it for them. In case a child overrides this constructor, this child
* must explicitly start the connection to prevent fatal errors. Also, $validator must be re-instantiated
*/
public function __construct() {
$this->startDBConnection();
$this->validator = new InputValidator();
}
public function __destruct() {
}
}
class Guest extends DataOperations implements DbInterface {
- - -
}
class Booking extends Guest implements DbInterface {
- - -
}
首先,当你看到我从父类中删除了抽象时,因为我假设只有那些方法是抽象的。第二,根据你的11个类的问题依赖于抽象类,我会说当你只删除抽象方法时,现在实现抽象方法的类应该实现接口。这是一次所需的任务。虽然使用其他常规抽象类方法的类像以前一样工作。