Как объявить абстрактный метод в неабстрактном классе в PHP? - PullRequest
50 голосов
/ 03 марта 2010
class absclass {
    abstract public function fuc();
}

отчеты:

Неустранимая ошибка PHP: класс absclass содержит 1 абстрактный метод и должен поэтому быть объявленным абстрактным или реализовать остальные методы (Absclass :: Fuc)

Я хочу знать, что означает реализовать остальные методы , как?

Ответы [ 7 ]

76 голосов
/ 03 марта 2010

См. Главу о Абстракция классов в руководстве по PHP :

PHP 5 представляет абстрактные классы и методы. Классы, определенные как абстрактные, не могут быть созданы, и любой класс, который содержит хотя бы один абстрактный метод, также должен быть абстрактным. Методы, определенные как абстрактные, просто объявляют сигнатуру метода - они не могут определить реализацию.

Это означает, что вы должны либо

abstract class absclass { // mark the entire class as abstract
    abstract public function fuc();
}

или

class absclass {
    public function fuc() { // implement the method body
        // which means it won't be abstract anymore
    };
}
27 голосов
/ 03 марта 2010

Я предполагаю, что оставшиеся методы на самом деле относятся к абстрактным методам, которые вы пытаетесь определить (в данном случае, fuc()), поскольку неабстрактные методы, которые могут существовать, в любом случае являются нормальными. Вероятно, это сообщение об ошибке, которое может использовать более качественную формулировку: там, где написано осталось , должно быть написано аннотация .

Исправление довольно простое (эта часть сообщения об ошибке в порядке): вам нужно изменить это:

abstract public function fuc();

... в правильную реализацию:

public function fuc(){
    // Code comes here
}

... или, альтернативно и в зависимости от ваших потребностей, сделать весь класс абстрактным:

abstract class absclass {
    abstract public function fuc();
}
26 голосов
/ 30 марта 2011

Абстрактный класс не может быть напрямую создан, но он может содержать как абстрактные, так и неабстрактные методы.

Если вы расширяете абстрактный класс, вы должны либо реализовать все его абстрактные функции, либо сделать абстрактный подкласс.

Вы не можете переопределить обычный метод и сделать его абстрактным, но вы должны (в конце концов) переопределить все абстрактные методы и сделать их неабстрактными.

<?php

abstract class Dog {

    private $name = null;
    private $gender = null;

    public function __construct($name, $gender) {
        $this->name = $name;
        $this->gender = $gender;
    }

    public function getName() {return $this->name;}
    public function setName($name) {$this->name = $name;}
    public function getGender() {return $this->gender;}
    public function setGender($gender) {$this->gender = $gender;}

    abstract public function bark();

}

// non-abstract class inheritting from an abstract class - this one has to implement all inherited abstract methods.
class Daschund extends Dog {
    public function bark() {
        print "bowowwaoar" . PHP_EOL;
    }
}

// this class causes a compilation error, because it fails to implement bark().
class BadDog extends Dog {
    // boom!  where's bark() ?
}

// this one succeeds in compiling, 
// it's passing the buck of implementing it's inheritted abstract methods on to sub classes.
abstract class PassTheBuckDog extends Dog {
    // no boom. only non-abstract subclasses have to bark(). 
}

$dog = new Daschund('Fred', 'male');
$dog->setGender('female');

print "name: " . $dog->getName() . PHP_EOL;
print "gender: ". $dog->getGender() . PHP_EOL;

$dog->bark();

?>

Эта программа бомбы с:

PHP Неустранимая ошибка: класс BadDog содержит 1 абстрактный метод и должен поэтому быть объявленным абстрактным или реализовать остальные методы (Собака :: кора)

Если вы закомментируете класс BadDog, то вы получите:

name: Fred
gender: female
bowowwaoar

Если вы попытаетесь создать экземпляр Dog или PassTheBuckDog напрямую, например:

$wrong = new Dog('somma','it');
$bad = new PassTheBuckDog('phamous','monster');

.. это бомбы с:

Неустранимая ошибка PHP: не удается создать экземпляр абстрактный класс Dog

или (если вы закомментируете неправильную строку $)

Неустранимая ошибка PHP: не удается создать экземпляр абстрактный класс PassTheBuckDog

Однако вы можете вызвать статическую функцию абстрактного класса:

abstract class Dog {
    ..
    public static function getBarker($classname, $name, $gender) {
        return new $classname($name, $gender);
    }
    ..
}

..

$other_dog = Dog::getBarker('Daschund', 'Wilma', 'female');
$other_dog->bark();

Это прекрасно работает.

3 голосов
/ 23 июня 2011

Абстрактные ключевые слова используются для обозначения классов или методов как шаблонов. Он похож на интерфейсы, но может содержать переменные и реализации методов.

Существует множество недоразумений относительно абстрактных классов. Вот пример абстрактного класса Dog. Если разработчик хочет создать некоторый базовый класс Dog для других разработчиков или для себя самого, он объявляет этот класс абстрактным. Вы не можете создать экземпляр класса Dog напрямую (никто не может), но вы можете расширить Dog своим собственным классом. SmartDog расширяет Dog и т. Д.

Все методы, которые объявлены как абстрактные классом Dog, должны быть реализованы вручную в каждом классе, расширяющем Dog.

Например, абстрактный класс Dog имеет абстрактный метод Dog :: Bark (). Но все собаки лают по-разному. Таким образом, в каждом подклассе Dog вы должны конкретно описывать, КАК собака лает, поэтому вы должны определить, например, SmartDog :: Bark ().

2 голосов
/ 03 марта 2010

Это сообщение об ошибке слегка сбивает вас с толку. В этом случае, поскольку именно в этот класс определяется fuc, в действительности не имеет смысла реализовывать его в этом классе. Ошибка пытается сказать вам, что неабстрактный класс не может иметь абстрактных методов. Как только вы поместите абстрактный метод в определение класса, вы также должны пометить сам класс как абстрактный.

2 голосов
/ 03 марта 2010

Это означает, что собственно абстрактный класс имеет хотя бы один абстрактный метод. Таким образом, ваш класс должен либо реализовать метод (не абстрактный), либо быть объявленным абстрактным.

0 голосов
/ 30 августа 2013

Я хотел использовать абстрактный метод внутри неабстрактного класса (нормальный класс?) И обнаружил, что могу обернуть содержимое метода в оператор if если get_parent_class (), например так:

if (get_parent_class($this) !== false) {

Или в действии (проверено в файле в строке cmd: php -f "abstract_method_normal_class_test.php"):

<?php
    class dad {
        function dad() {
            if (get_parent_class($this) !== false) {
                // implements some logic
                echo "I'm " , get_class($this) , "\n";
            } else {
                echo "I'm " , get_class($this) , "\n";
            }
        }
    }

    class child extends dad {
        function child() {
            parent::dad();
        }
    }

    $foo = new dad();
    $bar = new child();
?>

Output:
I'm dad
I'm child

PHP get_parent_class () Документация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...