Как объявить абстрактный метод в не-абстрактном классе в PHP?

class absclass { abstract public function fuc(); } 

доклады:

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

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

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

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

 abstract public function fuc(); 

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

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

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

 abstract class absclass { abstract public function fuc(); } 

См. Главу « Абстракция класса» в руководстве по 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 }; } 

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

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

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

 <?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 абстрактный метод и поэтому должен быть объявлен абстрактным или реализовать оставшиеся методы (Dog :: bark)

Если вы закомментируете класс 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(); 

Это работает отлично.

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

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

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

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

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

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

Я хотел использовать абстрактный метод в не-абстрактном классе (обычный класс?) И обнаружил, что я мог бы обернуть содержимое метода в оператор «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 () Документация