在PHP中实现抽象方法错误

时间:2012-06-25 02:26:40

标签: php oop abstract

我在这里创建了一个包含抽象方法的类,它总是将这些错误返回给我,即使该方法被声明为abstract。这是我的整个代码

<?php
interface Validator{
    public function isValid($input);
    public function getErrors();
}

class Validator_AbstractValidator
{
    protected $_errors = array();

    abstract public function isValid($input);

    public function getErrors()
    {
        return $this->_errors;
    }

    protected function _addError($message){
        $this_errors[] = $message;
    }
}

class Validator_MinimumLength extends Validator_AbstractValidator
{
    protected  $_minLength;

    public function __construct($minLength)
    {
        $this_minLength = $minLength;
    }

    public function isValid($input){
         if (strlen($input) > $this->_minLength) {
            return true;
        } else {
            $this->_addError("Input must be at least {$this_minLength}");
            return false;
        }
    }
}

class Validator_NoSpaces extends Validator_AbstractValidator{

    public function isValid($input) {
        if (preg_match('/\s/', $input)){
            $this->_addError("Spaces are not allowed");
            return false;
        }
        return true;
    }
}


interface Form_ElementInterface extends Validator{ }

class Form_Element_AbstractElement extends Validator_AbstractValidator implements Form_ElementInterface
{

    protected $_validators = array();

    public function addValidator(Validator $validator)
    {
        $this->_validators[] = $validator;
    }

    public function getValidators()
    {
        return $this->_validators;
    }

    protected function _addErrors(array $errors)
    {
        foreach ($errors as $error) {
            $this->_addError($error);
        }
    }

    public function hasErrors()
    {
        return (count($this->getErrors()) !== 0);
    }

    public function isValid($input)
    {
        foreach ($this->_validators as $validator) {
            if (!$validator->isValid($input)) {
                $this->_addErrors($validator->getErrors());
            }
        }
        return !$this->hadErrors();
    }
}

class Form_Element extends Form_Element_AbstractElement
{
    public function __construct($value,$minLength = 8)
    {
        $this->addValidator(new Validator_NoSpaces($value));
        $this->addValidator(new Validator_MinimumLength($minLength));
        //...
    }
}

错误是这个致命错误:类Validator_AbstractValidator包含1个抽象方法,因此必须声明为abstract或在C:\ xampp \ htdocs \ beatbeast \ includes \ Db \ Validator.php中实现其余方法(Validator_AbstractValidator :: isValid)在第21行

但第21行只包含此

}

有什么我错过的吗?

即使我在Class Validator_AbstractValidator类中添加了键控抽象我遇到了这个问题

Fatal error: Can't inherit abstract function Validator::isValid() (previously declared abstract in Validator_AbstractValidator) in C:\xampp\htdocs\beatbeast\includes\Db\Validator.php on line 57

但是第57行再次只包含此

{

3 个答案:

答案 0 :(得分:4)

  

PHP 5引入了抽象类和方法。不允许这样做   创建已定义为抽象的类的实例。任何   包含至少一个抽象方法的类也必须是   抽象。定义为抽象的方法只是声明方法的   签名他们无法定义实施。

如果一个类未被声明为abstract,则它不能包含任何抽象方法。

abstract class Validator_AbstractValidator
{
    //...
}

<强>更新

class Form_Element_AbstractElement extends Validator_AbstractValidator implements Form_ElementInterface

您正在扩展一个抽象类(Validator_AbstractValidator)并同时实现接口Validator,这是不可能的。

扩展类并单独实现接口,并在单独的类中实现接口Validator,而不是Validator_AbstractValidator,因为它是您之前已经声明过的抽象类。

实施接口验证器:

class from_validator_interface implement Validator{
    // you have to implement all the methods declared in the interface, in your case
    // `isValid` and `getErrors` both methods have to be implemented
}

扩展抽象类Validator_AbstractValidator:

class someClass extends Validator_AbstractValidator{
    // you don't need to implement all the abstract methods like interface
}

一些有用的链接: php.netothermore

答案 1 :(得分:0)

我将abstract添加到Validator_AbstractValidator后,您的代码可以正常使用,您说您已经这样做了。

abstract class Validator_AbstractValidator
{ ...

答案 2 :(得分:-1)

我在以下代码中遇到了同样的错误:

Interface Fruit
{
   public function getCalories() ;
   public function countSeeds() ;
}

Interface Vegetable
{
   public function getVitamins() ;
   public function getCalories() ;
}

class Tomato implements Fruit, Vegetable
{
   ...
}

这是我的解决方案,我添加了第三个父接口。

Interface Food 
{
    public function getCalories() ;
}

Interface Fruit extends Food
{

   public function countSeeds() ;
}

Interface Vegetable extends Food
{
   public function getVitamins() ;
}

class Tomato implements Fruit, Vegetable
{
   ...
}