2010-03-03 3 views
41
class absclass { 
    abstract public function fuc(); 
} 

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

PHP Fatal error: Class absclass contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (absclass::fuc)

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

+0

Он был уже объявлен в абстрактном классе предка вы inher но не реализованы. Теперь вам нужно реализовать его, а не объявлять. Как только все абстрактные (объявленные без реализаций) методы реализованы, класс становится не абстрактным и может иметь экземпляры. – Gherman

ответ

22

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

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

abstract public function fuc(); 

... в надлежащей реализации:

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

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

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

Я согласен с ** ошибочным сообщением об ошибке ** – user198729

+21

Как это возможно ответ? «Остальные методы» в этом случае относятся к «fuc», как говорится в сообщении об ошибке, поскольку вы объявили его абстрактным, но не объявили абстрактный абзац класса. Сообщение об ошибке, похоже, прекрасно написано. –

+4

@RobertGrant - если сообщение было прекрасно сформулировано, этот вопрос не был бы задан в первую очередь. – SDC

2

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

2

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

71

См. главу Class Abstraction in the PHP manual:

PHP 5 introduces abstract classes and methods. Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature - they cannot define the implementation.

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

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 
    }; 
} 
+1

Является ли «любой класс, содержащий хотя бы один абстрактный метод, также абстрактным», свойственным PHP или достаточно распространены в языках OO? – Caltor

+0

Это то же самое в F #, например – broch

25

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

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

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

<?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 Fatal error: Class BadDog contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Dog::bark)

Если закомментировать класс BadDog, то выход:

name: Fred 
gender: female 
bowowwaoar 

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

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

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

PHP Fatal error: Cannot instantiate abstract class Dog

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

PHP Fatal error: Cannot instantiate abstract class 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(); 

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

+0

'public public function bark()'? – Raptor

+0

О, спасибо, что указали это. Отредактировано и исправлено. – Shavais

3

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

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

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

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

0

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

Смежные вопросы